From 7e890d68b3042fc377d94bc923bd26c04a3376cf Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Thu, 2 Mar 2017 17:17:53 +0800 Subject: [PATCH 01/89] qcacmn: tdls module init and deinit tdls module init and deinit Change-Id: I751a948a46ac4e5148e35aa509fdbff25b6c5f3c CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 23 + core/src/wlan_tdls_cmds_process.h | 23 + core/src/wlan_tdls_ct.c | 23 + core/src/wlan_tdls_ct.h | 23 + core/src/wlan_tdls_main.c | 159 ++++++ core/src/wlan_tdls_main.h | 407 +++++++++++++++ core/src/wlan_tdls_mgmt.c | 23 + core/src/wlan_tdls_mgmt.h | 23 + core/src/wlan_tdls_txrx.c | 23 + core/src/wlan_tdls_txrx.h | 23 + dispatcher/inc/wlan_tdls_public_structs.h | 607 ++++++++++++++++++++++ dispatcher/inc/wlan_tdls_tgt_api.h | 23 + dispatcher/inc/wlan_tdls_ucfg_api.h | 78 +++ dispatcher/src/wlan_tdls_tgt_api.c | 23 + dispatcher/src/wlan_tdls_ucfg_api.c | 205 ++++++++ dispatcher/src/wlan_tdls_utils_api.c | 23 + 16 files changed, 1709 insertions(+) create mode 100644 core/src/wlan_tdls_cmds_process.c create mode 100644 core/src/wlan_tdls_cmds_process.h create mode 100644 core/src/wlan_tdls_ct.c create mode 100644 core/src/wlan_tdls_ct.h create mode 100644 core/src/wlan_tdls_main.c create mode 100644 core/src/wlan_tdls_main.h create mode 100644 core/src/wlan_tdls_mgmt.c create mode 100644 core/src/wlan_tdls_mgmt.h create mode 100644 core/src/wlan_tdls_txrx.c create mode 100644 core/src/wlan_tdls_txrx.h create mode 100644 dispatcher/inc/wlan_tdls_public_structs.h create mode 100644 dispatcher/inc/wlan_tdls_tgt_api.h create mode 100644 dispatcher/inc/wlan_tdls_ucfg_api.h create mode 100644 dispatcher/src/wlan_tdls_tgt_api.c create mode 100644 dispatcher/src/wlan_tdls_ucfg_api.c create mode 100644 dispatcher/src/wlan_tdls_utils_api.c diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c new file mode 100644 index 0000000000..7a6aa6cb49 --- /dev/null +++ b/core/src/wlan_tdls_cmds_process.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_cmds_process.c + * + * TDLS north bound commands implementation + */ diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h new file mode 100644 index 0000000000..a90931846a --- /dev/null +++ b/core/src/wlan_tdls_cmds_process.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_cmds_process.h + * + * TDLS north bound commands include file + */ diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c new file mode 100644 index 0000000000..851d0a1999 --- /dev/null +++ b/core/src/wlan_tdls_ct.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_ct.c + * + * TDLS connection tracker function definitions + */ diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h new file mode 100644 index 0000000000..473f2b5566 --- /dev/null +++ b/core/src/wlan_tdls_ct.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_ct.h + * + * TDLS connection tracker api declaration + */ diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c new file mode 100644 index 0000000000..eef8915fb3 --- /dev/null +++ b/core/src/wlan_tdls_main.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_main.c + * + * TDLS core function definitions + */ + +#include "wlan_tdls_main.h" + +QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj)); + if (tdls_soc_obj == NULL) { + tdls_err("Failed to allocate memory for tdls object"); + return QDF_STATUS_E_NOMEM; + } + + tdls_soc_obj->soc = psoc; + + status = wlan_objmgr_psoc_component_obj_attach(psoc, + WLAN_UMAC_COMP_TDLS, + (void *)tdls_soc_obj, + QDF_STATUS_SUCCESS); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to attach psoc tdls component"); + qdf_mem_free(tdls_soc_obj); + } + + tdls_notice("TDLS obj attach to psoc successfully"); + + return status; +} + +QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (tdls_soc_obj == NULL) { + tdls_err("Failed to get tdls obj in psoc"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_psoc_component_obj_detach(psoc, + WLAN_UMAC_COMP_TDLS, + tdls_soc_obj); + + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to detach psoc tdls component"); + + qdf_mem_free(tdls_soc_obj); + + return status; +} + +static void tdls_vdev_init(struct tdls_vdev_priv_obj *vdev) +{ + uint8_t i; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + qdf_list_create(&vdev->peer_list[i], + WLAN_TDLS_PEER_SUB_LIST_SIZE); + } + + qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev); + qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev); +} + +QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, + void *arg) +{ + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + + tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + /* TODO: Add concurrency check */ + + tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); + if (tdls_vdev_obj == NULL) { + tdls_err("Failed to allocate memory for tdls vdev object"); + return QDF_STATUS_E_NOMEM; + } + + tdls_vdev_obj->vdev = vdev; + tdls_vdev_init(tdls_vdev_obj); + + status = wlan_objmgr_vdev_component_obj_attach(vdev, + WLAN_UMAC_COMP_TDLS, + (void *)tdls_vdev_obj, + QDF_STATUS_SUCCESS); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to attach vdev tdls component"); + qdf_mem_free(tdls_vdev_obj); + } + + tdls_notice("tdls object attach to vdev successfully"); + + return status; +} + +QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, + void *arg) +{ + QDF_STATUS status; + void *tdls_vdev_obj; + + tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_SUCCESS; + + tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (tdls_vdev_obj == NULL) { + tdls_err("Failed to get tdls vdev object"); + return QDF_STATUS_E_FAILURE; + } + + status = wlan_objmgr_vdev_component_obj_detach(vdev, + WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to detach vdev tdls component"); + + qdf_mem_free(tdls_vdev_obj); + + return status; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h new file mode 100644 index 0000000000..b85c74cc5f --- /dev/null +++ b/core/src/wlan_tdls_main.h @@ -0,0 +1,407 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_main.h + * + * TDLS core function declaration + */ + +#if !defined(_WLAN_TDLS_MAIN_H_) +#define _WLAN_TDLS_MAIN_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* Bit mask flag for tdls_option to FW */ +#define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ +#define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ +#define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ + +#define tdls_log(level, args...) \ + QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) +#define tdls_logfl(level, format, args...) \ + tdls_log(level, FL(format), ## args) + +#define tdls_debug(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) +#define tdls_notice(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) +#define tdls_warn(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) +#define tdls_err(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) +#define tdls_alert(format, args...) \ + tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) + +#define TDLS_IS_CONNECTED(peer) \ + ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ + (TDLS_LINK_TEARING == (peer)->link_status)) + +#define SET_BIT(value, mask) ((value) |= (1 << (mask))) +#define CLEAR_BIT(value, mask) ((value) &= ~(1 << (mask))) +#define CHECK_BIT(value, mask) ((value) & (1 << (mask))) +/** + * struct tdls_conn_info - TDLS connection record + * @session_id: session id + * @sta_id: sta id + * @peer_mac: peer address + */ +struct tdls_conn_info { + uint8_t session_id; + uint8_t sta_id; + struct qdf_mac_addr peer_mac; +}; + +/** + * enum tdls_nss_transition_state - TDLS NSS transition states + * @TDLS_NSS_TRANSITION_UNKNOWN: default state + * @TDLS_NSS_TRANSITION_2x2_to_1x1: transition from 2x2 to 1x1 stream + * @TDLS_NSS_TRANSITION_1x1_to_2x2: transition from 1x1 to 2x2 stream + */ +enum tdls_nss_transition_state { + TDLS_NSS_TRANSITION_S_UNKNOWN = 0, + TDLS_NSS_TRANSITION_S_2x2_to_1x1, + TDLS_NSS_TRANSITION_S_1x1_to_2x2, +}; + +/** + * enum tdls_command_type - TDLS command type + * @TDLS_CMD_TX_ACTION: send tdls action frame + * @TDLS_CMD_ADD_STA: add tdls peer + * @TDLS_CMD_CHANGE_STA: change tdls peer + * @TDLS_CMD_ENABLE_LINK: enable tdls link + * @TDLS_CMD_DISABLE_LINK: disable tdls link + * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer + * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer + * @TDLS_CMD_STATS_UPDATE: update tdls stats + * @TDLS_CMD_CONFIG_UPDATE: config tdls + */ +enum tdls_commmand_type { + TDLS_CMD_TX_ACTION = 1, + TDLS_CMD_ADD_STA, + TDLS_CMD_CHANGE_STA, + TDLS_CMD_ENABLE_LINK, + TDLS_CMD_DISABLE_LINK, + TDLS_CMD_CONFIG_FORCE_PEER, + TDLS_CMD_REMOVE_FORCE_PEER, + TDLS_CMD_STATS_UPDATE, + TDLS_CMD_CONFIG_UPDATE +}; + +/** + * struct tdls_conn_tracker_mac_table - connection tracker peer table + * @mac_address: peer mac address + * @tx_packet_cnt: number of tx pkts + * @rx_packet_cnt: number of rx pkts + * @peer_timestamp_ms: time stamp of latest peer traffic + */ +struct tdls_conn_tracker_mac_table { + struct qdf_mac_addr mac_address; + uint32_t tx_packet_cnt; + uint32_t rx_packet_cnt; + uint32_t peer_timestamp_ms; +}; + +/** + * struct tdls_set_state_db - to record set tdls state command, we need to + * set correct tdls state to firmware: + * 1. enable tdls in firmware before tdls connection; + * 2. disable tdls if concurrency happen, before disable tdls, all active peer + * should be deleted in firmware. + * + * @set_state_cnt: tdls set state count + * @vdev_id: vdev id of last set state command + */ +struct tdls_set_state_info { + uint8_t set_state_cnt; + uint8_t vdev_id; +}; + +/** + * struct tdls_psoc_priv_ctx - tdls context + * @soc: objmgr psoc + * @tdls_current_mode: current tdls mode + * @tdls_user_config_mode: user configure tdls mode + * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type + * of peer object to get the active tdls peers + * @tdls_configs: tdls user configure + * @max_num_tdls_sta: maximum TDLS station number allowed upon runtime condition + * @connected_peer_count: tdls peer connected count + * @tdls_off_channel: tdls off channel number + * @tdls_channel_offset: tdls channel offset + * @tdls_fw_off_chan_mode: tdls fw off channel mode + * @enable_tdls_connection_tracker: enable tdls connection tracker + * @tdls_external_peer_count: external tdls peer count + * @tdls_nss_switch_in_progress: tdls antenna switch in progress + * @tdls_nss_teardown_complete: tdls tear down complete + * @tdls_nss_transition_mode: tdls nss transition mode + * @tdls_teardown_peers_cnt: tdls tear down peer count + * @tdls_tx_cnf_cb: callback registered by hdd to receive the ack cnf + * @set_state_info: set tdls state info + * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb + * @tdls_event_cb: tdls event callback + * @tdls_evt_cb_data: tdls event user data + * @tx_q_ack: queue for tx frames waiting for ack + * @tdls_con_cap: tdls concurrency support + */ +struct tdls_soc_priv_obj { + struct wlan_objmgr_psoc *soc; + enum tdls_support_mode tdls_current_mode; + enum tdls_support_mode tdls_user_config_mode; + struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; + struct tdls_user_config tdls_configs; + uint16_t max_num_tdls_sta; + uint16_t connected_peer_count; + uint8_t tdls_off_channel; + uint16_t tdls_channel_offset; + int32_t tdls_fw_off_chan_mode; + bool enable_tdls_connection_tracker; + uint8_t tdls_external_peer_count; + bool tdls_nss_switch_in_progress; + bool tdls_nss_teardown_complete; + enum tdls_nss_transition_state tdls_nss_transition_mode; + int32_t tdls_teardown_peers_cnt; + struct tdls_set_state_info set_state_info; + tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; + void *tx_ack_cnf_cb_data; + tdls_evt_callback tdls_event_cb; + void *tdls_evt_cb_data; + qdf_list_t tx_q_ack; + enum tdls_conc_cap tdls_con_cap; +}; + +/** + * struct tdls_vdev_priv_obj - tdls private vdev object + * @vdev: vdev objmgr object + * @peer_list: tdls peer list on this vdev + * @peer_update_timer: connection tracker timer + * @peer_dicovery_timer: peer discovery timer + * @threshold_config: threshold config + * @discovery_peer_cnt: discovery peer count + * @discovery_sent_cnt: discovery sent count + * @ap_rssi: ap rssi + * @curr_candidate: current candidate + * @ct_peer_table: linear mac address table for counting the packets + * @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table + * @magic: magic + * @tx_queue: tx frame queue + */ +struct tdls_vdev_priv_obj { + struct wlan_objmgr_vdev *vdev; + qdf_list_t peer_list[WLAN_TDLS_PEER_LIST_SIZE]; + qdf_mc_timer_t peer_update_timer; + qdf_mc_timer_t peer_discovery_timer; + struct tdls_config_params threshold_config; + int32_t discovery_peer_cnt; + uint32_t discovery_sent_cnt; + int8_t ap_rssi; + struct tdls_peer *curr_candidate; + struct tdls_conn_tracker_mac_table + ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE]; + uint8_t valid_mac_entries; + uint32_t magic; + qdf_list_t tx_queue; +}; + +/** + * struct tdls_peer - tdls peer data + * @node: node + * @vdev_priv: tdls vdev priv obj + * @peer_mac: peer mac address + * @sta_id: station identifier + * @rssi: rssi + * @tdls_support: tdls support + * @link_status: tdls link status + * @signature: signature + * @is_responder: is responder + * @discovery_processed: dicovery processed + * @discovery_attempt: discovery attempt + * @tx_pkt: tx packet + * @rx_pkt: rx packet + * @uapsd_queues: uapsd queues + * @max_sp: max sp + * @buf_sta_capable: is buffer sta + * @off_channel_capable: is offchannel supported flag + * @supported_channels_len: supported channels length + * @supported_channels: supported channels + * @supported_oper_classes_len: supported operation classes length + * @supported_oper_classes: supported operation classes + * @is_forced_peer: is forced peer + * @op_class_for_pref_off_chan: op class for preferred off channel + * @pref_off_chan_num: preferred off channel number + * @op_class_for_pref_off_chan_is_set: op class for preferred off channel set + * @peer_idle_timer: time to check idle traffic in tdls peers + * @is_peer_idle_timer_initialised: Flag to check idle timer init + * @spatial_streams: Number of TX/RX spatial streams for TDLS + * @reason: reason + * @state_change_notification: state change notification + * @qos: QOS capability of TDLS link + */ +struct tdls_peer { + qdf_list_node_t node; + struct tdls_vdev_priv_obj *vdev_priv; + struct qdf_mac_addr peer_mac; + uint16_t sta_id; + int8_t rssi; + enum tdls_peer_capab tdls_support; + enum tdls_link_status link_status; + uint8_t signature; + uint8_t is_responder; + uint8_t discovery_processed; + uint16_t discovery_attempt; + uint16_t tx_pkt; + uint16_t rx_pkt; + uint8_t uapsd_queues; + uint8_t max_sp; + uint8_t buf_sta_capable; + uint8_t off_channel_capable; + uint8_t supported_channels_len; + uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t supported_oper_classes_len; + uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; + bool is_forced_peer; + uint8_t op_class_for_pref_off_chan; + uint8_t pref_off_chan_num; + uint8_t op_class_for_pref_off_chan_is_set; + qdf_mc_timer_t peer_idle_timer; + bool is_peer_idle_timer_initialised; + uint8_t spatial_streams; + enum tdls_link_reason reason; + tdls_state_change_callback state_change_notification; + uint8_t qos; +}; + +/** + * wlan_vdev_get_tdls_soc_obj - private API to get tdls soc object from vdev + * @vdev: vdev object + * + * Return: tdls soc object + */ +static inline struct tdls_soc_priv_obj * +wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_psoc *psoc = + wlan_pdev_get_psoc(wlan_vdev_get_pdev(vdev)); + + return (struct tdls_soc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); +} + +/** + * wlan_psoc_get_tdls_soc_obj - private API to get tdls soc object from psoc + * @psoc: psoc object + * + * Return: tdls soc object + */ +static inline struct tdls_soc_priv_obj * +wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) +{ + return (struct tdls_soc_priv_obj *) + wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); +} + +/** + * wlan_vdev_get_tdls_vdev_obj - private API to get tdls vdev object from vdev + * @vdev: vdev object + * + * Return: tdls vdev object + */ +static inline struct tdls_vdev_priv_obj * +wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) +{ + return (struct tdls_vdev_priv_obj *) + wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); +} + +/** + * tdls_set_link_status - tdls set link status + * @vdev: vdev object + * @mac: mac address of tdls peer + * @link_status: tdls link status + * @link_reason: reason + */ +void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev, + const uint8_t *mac, + enum tdls_link_status link_status, + enum tdls_link_reason link_reason); +/** + * tdls_psoc_obj_create_notification() - tdls psoc create notification handler + * @psoc: psoc object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * tdls_psoc_obj_destroy_notification() - tdls psoc destroy notification handler + * @psoc: psoc object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, + void *arg_list); + +/** + * tdls_vdev_obj_create_notification() - tdls vdev create notification handler + * @vdev: vdev object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, + void *arg_list); + +/** + * tdls_vdev_obj_destroy_notification() - tdls vdev destroy notification handler + * @vdev: vdev object + * @arg_list: Argument list + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, + void *arg_list); + +/** + * tdls_process_cmd() - tdls main command process function + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg); + +/** + * tdls_process_evt() - tdls main event process function + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_evt(struct scheduler_msg *msg); +#endif diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c new file mode 100644 index 0000000000..a8e5f87980 --- /dev/null +++ b/core/src/wlan_tdls_mgmt.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_mgmt.c + * + * TDLS management frames implementation + */ diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h new file mode 100644 index 0000000000..1abd248412 --- /dev/null +++ b/core/src/wlan_tdls_mgmt.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_mgmt.h + * + * TDLS management frames include file + */ diff --git a/core/src/wlan_tdls_txrx.c b/core/src/wlan_tdls_txrx.c new file mode 100644 index 0000000000..6ded57c974 --- /dev/null +++ b/core/src/wlan_tdls_txrx.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_txrx.c + * + * TDLS txrx function definitions + */ diff --git a/core/src/wlan_tdls_txrx.h b/core/src/wlan_tdls_txrx.h new file mode 100644 index 0000000000..b001ffe745 --- /dev/null +++ b/core/src/wlan_tdls_txrx.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_txrx.h + * + * TDLS txrx api declaration + */ diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h new file mode 100644 index 0000000000..d9b5d8da98 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -0,0 +1,607 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_public_structs.h + * + * TDLS public structure definations + */ + +#ifndef _WLAN_TDLS_STRUCTS_H_ +#define _WLAN_TDLS_STRUCTS_H_ +#include +#include +#include +#include +#include + +#define WLAN_TDLS_STA_MAX_NUM 8 +#define WLAN_TDLS_PEER_LIST_SIZE 256 +#define WLAN_TDLS_CT_TABLE_SIZE 8 +#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 +#define WLAN_MAC_MAX_EXTN_CAP 8 +#define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAX_SUPP_OPER_CLASSES 32 +#define WLAN_MAC_MAX_SUPP_RATES 32 +#define ENABLE_CHANSWITCH 1 + +#define TDLS_STA_INDEX_CHECK(sta_id) \ + (((sta_id) >= 1) && ((sta_id) < 0xFF)) +/** + * enum tdls_conc_cap - tdls concurrency support + * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls + * @TDLS_SUPPORTED_ONLY_ON_P2P_CLIENT: only support p2p client tdls + */ +enum tdls_conc_cap { + TDLS_SUPPORTED_ONLY_ON_STA = 0, + TDLS_SUPPORTED_ONLY_ON_P2P_CLIENT, +}; + +/** + * enum tdls_peer_capab - tdls capability type + * @TDLS_CAP_NOT_SUPPORTED: tdls not supported + * @TDLS_CAP_UNKNOWN: unknown capability + * @TDLS_CAP_SUPPORTED: tdls capability supported + */ +enum tdls_peer_capab { + TDLS_CAP_NOT_SUPPORTED = -1, + TDLS_CAP_UNKNOWN = 0, + TDLS_CAP_SUPPORTED = 1, +}; + +/** + * enum tdls_link_status - tdls link status + * @TDLS_LINK_IDLE: tdls link idle + * @TDLS_LINK_DISCOVERING: tdls link discovering + * @TDLS_LINK_DISCOVERED: tdls link discovered + * @TDLS_LINK_CONNECTING: tdls link connecting + * @TDLS_LINK_CONNECTED: tdls link connected + * @TDLS_LINK_TEARING: tdls link tearing + */ +enum tdls_link_status { + TDLS_LINK_IDLE = 0, + TDLS_LINK_DISCOVERING, + TDLS_LINK_DISCOVERED, + TDLS_LINK_CONNECTING, + TDLS_LINK_CONNECTED, + TDLS_LINK_TEARING, +}; + +/** + * enum tdls_link_reason - tdls link reason + * @TDLS_LINK_SUCCESS: Success + * @TDLS_LINK_UNSPECIFIED: Unspecified reason + * @TDLS_LINK_NOT_SUPPORTED: Remote side doesn't support TDLS + * @TDLS_LINK_UNSUPPORTED_BAND: Remote side doesn't support this band + * @TDLS_LINK_NOT_BENEFICIAL: Going to AP is better than direct + * @TDLS_LINK_DROPPED_BY_REMOTE: Remote side doesn't want it anymore + */ +enum tdls_link_reason { + TDLS_LINK_SUCCESS, + TDLS_LINK_UNSPECIFIED = -1, + TDLS_LINK_NOT_SUPPORTED = -2, + TDLS_LINK_UNSUPPORTED_BAND = -3, + TDLS_LINK_NOT_BENEFICIAL = -4, + TDLS_LINK_DROPPED_BY_REMOTE = -5, +}; + +/** + * enum tdls_support_mode - TDLS support mode + * @TDLS_SUPPORT_DISABLED: Disabled in ini or FW + * @TDLS_SUPPORT_SUSPENDED: TDLS supported by ini and FW, but disabled + * temporarily due to off-channel operations or due to other reasons + * @TDLS_SUPPORT_EXP_TRIG_ONLY: Explicit trigger mode + * @TDLS_SUPPORT_IMP_MODE: Implicit mode + * @TDLS_SUPPORT_EXT_CONTROL: External control mode + */ +enum tdls_support_mode { + TDLS_SUPPORT_DISABLED = 0, + TDLS_SUPPORT_SUSPENDED, + TDLS_SUPPORT_EXP_TRIG_ONLY, + TDLS_SUPPORT_IMP_MODE, + TDLS_SUPPORT_EXT_CONTROL, +}; + +/** + * enum tdls_event_type - TDLS event type + * @TDLS_EVENT_VDEV_STATE_CHANGE: umac connect/disconnect event + * @TDLS_EVENT_MGMT_TX_ACK_CNF: tx tdls frame ack event + * @TDLS_EVENT_RX_MGMT: rx discovery response frame + * @TDLS_EVENT_ADD_PEER: add peer or update peer + * @TDLS_EVENT_DEL_PEER: delete peer + */ +enum tdls_event_type { + TDLS_EVENT_VDEV_STATE_CHANGE = 0, + TDLS_EVENT_MGMT_TX_ACK_CNF, + TDLS_EVENT_RX_MGMT, + TDLS_EVENT_ADD_PEER, + TDLS_EVENT_DEL_PEER, +}; + +/** + * enum tdls_state_t - tdls state + * + * @QCA_WIFI_HAL_TDLS_DISABLED: TDLS is not enabled, or is disabled now + * @QCA_WIFI_HAL_TDLS_ENABLED: TDLS is enabled, but not yet tried + * @QCA_WIFI_HAL_TDLS_ESTABLISHED: Direct link is established + * @QCA_WIFI_HAL_TDLS_ESTABLISHED_OFF_CHANNEL: Direct link established using MCC + * @QCA_WIFI_HAL_TDLS_DROPPED: Direct link was established, but is now dropped + * @QCA_WIFI_HAL_TDLS_FAILED: Direct link failed + */ +enum tdls_state_t { + QCA_WIFI_HAL_TDLS_S_DISABLED = 1, + QCA_WIFI_HAL_TDLS_S_ENABLED, + QCA_WIFI_HAL_TDLS_S_ESTABLISHED, + QCA_WIFI_HAL_TDLS_S_ESTABLISHED_OFF_CHANNEL, + QCA_WIFI_HAL_TDLS_S_DROPPED, + QCA_WIFI_HAL_TDLS_S_FAILED, +}; + +/** + * enum tdls_event_msg_type - TDLS event message type + * @TDLS_SHOULD_DISCOVER: should do discover + * @TDLS_SHOULD_TEARDOWN: notify teardown the link + * @TDLS_PEER_DISCONNECTED: tdls peer disconnected + * @TDLS_CONNECTION_TRACKER_NOTIFY: connection tracker notify + */ +enum tdls_event_msg_type { + TDLS_SHOULD_DISCOVER = 0, + TDLS_SHOULD_TEARDOWN, + TDLS_PEER_DISCONNECTED, + TDLS_CONNECTION_TRACKER_NOTIFY, +}; + +/** + * enum tdls_event_reason - TDLS event reason + * @TDLS_TEARDOWN_TX: + * @TDLS_TEARDOWN_RSSI: + * @TDLS_TEARDOWN_SCAN: + * @TDLS_TEARDOWN_PTR_TIMEOUT: + * @TDLS_TEARDOWN_BAD_PTR: + * @TDLS_TEARDOWN_NO_RSP: + * @TDLS_DISCONNECTED_PEER_DELETE: + * @TDLS_PEER_ENTER_BUF_STA: + * @TDLS_PEER_EXIT_BUF_STA: + * @TDLS_ENTER_BT_BUSY: + * @TDLS_EXIT_BT_BUSY: + * @DLS_SCAN_STARTED: + * @TDLS_SCAN_COMPLETED: + */ +enum tdls_event_reason { + TDLS_TEARDOWN_TX, + TDLS_TEARDOWN_RSSI, + TDLS_TEARDOWN_SCAN, + TDLS_TEARDOWN_PTR_TIMEOUT, + TDLS_TEARDOWN_BAD_PTR, + TDLS_TEARDOWN_NO_RSP, + TDLS_DISCONNECTED_PEER_DELETE, + TDLS_PEER_ENTER_BUF_STA, + TDLS_PEER_EXIT_BUF_STA, + TDLS_ENTER_BT_BUSY, + TDLS_EXIT_BT_BUSY, + TDLS_SCAN_STARTED, + TDLS_SCAN_COMPLETED, +}; + +/** + * struct tx_frame - tx frame + * @buf: frame buffer + * @buf_len: buffer length + * @tx_timer: tx send timer + */ +struct tx_frame { + uint8_t *buf; + size_t buf_len; + qdf_timer_t tx_timer; +}; + +/** + * enum tdls_feature_bit + * @TDLS_FEATURE_OFF_CHANNEL: tdls off channel + * @TDLS_FEATURE_WMM: tdls wmm + * @TDLS_FEATURE_BUFFER_STA: tdls buffer sta + * @TDLS_FEATURE_SLEEP_STA: tdls sleep sta feature + * @TDLS_FEATURE_SCAN: tdls scan + * @TDLS_FEATURE_ENABLE: tdls enabled + * @TDLS_FEAUTRE_IMPLICIT_TRIGGER: tdls implicit trigger + * @TDLS_FEATURE_EXTERNAL_CONTROL: tdls external control + */ +enum tdls_feature_bit { + TDLS_FEATURE_OFF_CHANNEL, + TDLS_FEATURE_WMM, + TDLS_FEATURE_BUFFER_STA, + TDLS_FEATURE_SLEEP_STA, + TDLS_FEATURE_SCAN, + TDLS_FEATURE_ENABLE, + TDLS_FEAUTRE_IMPLICIT_TRIGGER, + TDLS_FEATURE_EXTERNAL_CONTROL +}; + +#define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_OFF_CHANNEL, flags) +#define TDLS_IS_WMM_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_WMM, flags) +#define TDLS_IS_BUFFER_STA_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_BUFFER_STA, flags) +#define TDLS_IS_SLEEP_STA_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_SLEEP_STA, flags) +#define TDLS_IS_SCAN_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_SCAN, flags) +#define TDLS_IS_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_ENABLE, flags) +#define TDLS_IS_IMPLICIT_TRIG_ENABLED(flags) \ + CHECK_BIT(TDLS_FEAUTRE_IMPLICIT_TRIGGER, flags) +#define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ + CHECK_BIT(TDLS_FEATURE_EXTERNAL_CONTROL, flags) + +/** + * struct tdls_user_config - TDLS user configuration + * @tdls_tx_states_period: tdls tx states period + * @tdls_tx_pkt_threshold: tdls tx packets threshold + * @tdls_rx_pkt_threshold: tdls rx packets threshold + * @tdls_max_discovery_attempt: tdls discovery max times + * @tdls_idle_timeout: tdls idle timeout + * @tdls_idle_pkt_threshold: tdls idle packets threshold + * @tdls_rssi_trigger_threshold: tdls rssi trigger threshold + * @tdls_rssi_teardown_threshold: tdls rssi tear down threshold + * @tdls_rssi_delta: tdls rssi delta + * @tdls_uapsd_mask: tdls uapsd mask + * @tdls_uapsd_inactivity_time: tdls uapsd inactivity time + * @tdls_uapsd_pti_window: tdls peer traffic indication window + * @tdls_uapsd_ptr_timeout: tdls peer response timeout + * @tdls_feature_flags: tdls feature flags + * @tdls_pre_off_chan_num: tdls off channel number + * @tdls_pre_off_chan_bw: tdls off channel bandwidth + * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer + */ +struct tdls_user_config { + uint32_t tdls_tx_states_period; + uint32_t tdls_tx_pkt_threshold; + uint32_t tdls_rx_pkt_threshold; + uint32_t tdls_max_discovery_attempt; + uint32_t tdls_idle_timeoute; + uint32_t tdls_idle_pkt_threshold; + uint32_t tdls_rssi_trigger_threshold; + uint32_t tdls_rssi_teardown_threshold; + uint32_t tdls_rssi_delta; + uint32_t tdls_uapsd_mask; + uint32_t tdls_uapsd_inactivity_time; + uint32_t tdls_uapsd_pti_window; + uint32_t tdls_uapsd_ptr_timeout; + uint32_t tdls_feature_flags; + uint32_t tdls_pre_off_chan_num; + uint32_t tdls_pre_off_chan_bw; + uint32_t tdls_peer_kickout_threshold; +}; + +/** + * struct tdls_config_params - tdls configure paramets + * @tdls: tdls support mode + * @tx_period_t: tdls tx stats period + * @tx_packet_n: tdls tx packets number threshold + * @discovery_tries_n: tdls max discovery attempt count + * @idle_timeout_t: tdls idle time timeout + * @idle_packet_n: tdls idle pkt threshold + * @rssi_trigger_threshold: tdls rssi trigger threshold, checked before setup + * @rssi_teardown_threshold: tdls rssi teardown threshold + * @rssi_delta: rssi delta + */ +struct tdls_config_params { + uint32_t tdls; + uint32_t tx_period_t; + uint32_t tx_packet_n; + uint32_t discovery_tries_n; + uint32_t idle_timeout_t; + uint32_t idle_packet_n; + int32_t rssi_trigger_threshold; + int32_t rssi_teardown_threshold; + int32_t rssi_delta; +}; + +/** + * struct tdls_tx_cnf: tdls tx ack + * @vdev_id: vdev id + * @action_cookie: frame cookie + * @buf: frame buf + * @buf_len: buffer length + * @status: tx send status + */ +struct tdls_tx_cnf { + int vdev_id; + uint64_t action_cookie; + void *buf; + size_t buf_len; + int status; +}; + +/* This callback is used to report state change of peer to wpa_supplicant */ +typedef int (*tdls_state_change_callback)(const uint8_t *mac, + uint32_t opclass, + uint32_t channel, + uint32_t state, + int32_t reason, void *ctx); + +/* This callback is used to report events to os_if layer */ +typedef QDF_STATUS (*tdls_evt_callback) (void *data, + enum tdls_event_type ev_type, + void *event); + +/* prototype of callback registered by hdd to receive the ack cnf */ +typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, + struct tdls_tx_cnf *tx_ack_cnf_cb_data); + +/** + * struct tdls_start_params - tdls start params + * @tdls_event_cb: tdls event callback + * @tdls_evt_cb_data: tdls event data + * @ack_cnf_cb: tdls tx ack callback to indicate the tx status + * @tx_ack_cnf_cb_data: tdls tx ack user data + */ +struct tdls_start_params { + tdls_evt_callback tdls_event_cb; + void *tdls_evt_cb_data; + tdls_tx_ack_cnf_callback ack_cnf_cb; + void *tx_ack_cnf_cb_data; +}; + +/** + * struct tdls_add_peer_params - add peer request parameter + * @peer_addr: peer mac addr + * @peer_type: peer type + * @vdev_id: vdev id + */ +struct tdls_add_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; +}; + +/** + * struct tdls_add_peer_request - peer add request + * @vdev: vdev + * @add_peer_req: add peer request parameters + */ +struct tdls_add_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_add_peer_params add_peer_req; +}; + +/** + * struct tdls_del_peer_params - delete peer request parameter + * @peer_addr: peer mac addr + * @peer_type: peer type + * @vdev_id: vdev id + */ +struct tdls_del_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; +}; + +/** + * struct tdls_del_peer_request - peer delete request + * @vdev: vdev + * @del_peer_req: delete peer request parameters + */ +struct tdls_del_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_del_peer_params del_peer_req; +}; + +/** + * struct vhgmcsinfo - VHT MCS information + * @rx_mcs_map: RX MCS map 2 bits for each stream, total 8 streams + * @rx_highest: Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_mcs_map: TX MCS map 2 bits for each stream, total 8 streams + * @tx_highest: Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ +struct vhtmcsinfo { + uint16_t rx_mcs_map; + uint16_t rx_highest; + uint16_t tx_mcs_map; + uint16_t tx_highest; +}; + +/** + * struct vhtcap - VHT capabilities + * + * This structure is the "VHT capabilities element" as + * described in 802.11ac D3.0 8.4.2.160 + * @vht_cap_info: VHT capability info + * @supp_mcs: VHT MCS supported rates + */ +struct vhtcap { + uint32_t vht_capinfo; + struct vhtmcsinfo supp_mcs; +}; + +struct tdls_update_peer_params { + const uint8_t *peer_addr; + uint32_t peer_type; + uint32_t vdev_id; + uint16_t capability; + uint8_t extn_capability[WLAN_MAC_MAX_EXTN_CAP]; + uint8_t supported_rates_len; + uint8_t supported_rates[WLAN_MAC_MAX_SUPP_RATES]; + uint8_t htcap_present; + struct htcap_cmn_ie ht_cap; + uint8_t vhtcap_present; + struct vhtcap vht_cap; + uint8_t uapsd_queues; + uint8_t max_sp; + uint8_t supported_channels_len; + uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t supported_oper_classes_len; + uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; +}; + +struct tdls_update_peer_request { + struct wlan_objmgr_vdev *vdev; + struct tdls_update_peer_params update_peer_req; +}; + +/** + * struct tdls_info - tdls info + * + * @vdev_id: vdev id + * @tdls_state: tdls state + * @notification_interval_ms: notification interval in ms + * @tx_discovery_threshold: tx discovery threshold + * @tx_teardown_threshold: tx teardown threshold + * @rssi_teardown_threshold: rx teardown threshold + * @rssi_delta: rssi delta + * @tdls_options: tdls options + * @peer_traffic_ind_window: peer traffic indication window + * @peer_traffic_response_timeout: peer traffic response timeout + * @puapsd_mask: puapsd mask + * @puapsd_inactivity_time: puapsd inactivity time + * @puapsd_rx_frame_threshold: puapsd rx frame threshold + * @teardown_notification_ms: tdls teardown notification interval + * @tdls_peer_kickout_threshold: tdls packets threshold + * for peer kickout operation + */ +struct tdls_info { + uint32_t vdev_id; + uint32_t tdls_state; + uint32_t notification_interval_ms; + uint32_t tx_discovery_threshold; + uint32_t tx_teardown_threshold; + int32_t rssi_teardown_threshold; + int32_t rssi_delta; + uint32_t tdls_options; + uint32_t peer_traffic_ind_window; + uint32_t peer_traffic_response_timeout; + uint32_t puapsd_mask; + uint32_t puapsd_inactivity_time; + uint32_t puapsd_rx_frame_threshold; + uint32_t teardown_notification_ms; + uint32_t tdls_peer_kickout_threshold; +}; + +/** + * struct tdls_ch_params - channel parameters + * @chan_id: ID of the channel + * @pwr: power level + * @dfs_set: is dfs supported or not + * @half_rate: is the channel operating at 10MHz + * @quarter_rate: is the channel operating at 5MHz + */ +struct tdls_ch_params { + uint8_t chan_id; + uint8_t pwr; + bool dfs_set; + bool half_rate; + bool quarter_rate; +}; + +/** + * struct tdls_peer_params - TDLS peer capablities parameters + * @is_peer_responder: is peer responder or not + * @peer_uapsd_queue: peer uapsd queue + * @peer_max_sp: peer max SP value + * @peer_buff_sta_support: peer buffer sta supported or not + * @peer_off_chan_support: peer offchannel support + * @peer_curr_operclass: peer current operating class + * @self_curr_operclass: self current operating class + * @peer_chanlen: peer channel length + * @peer_chan: peer channel list + * @peer_oper_classlen: peer operating class length + * @peer_oper_class: peer operating class + * @pref_off_channum: peer offchannel number + * @pref_off_chan_bandwidth: peer offchannel bandwidth + * @opclass_for_prefoffchan: operating class for offchannel + */ +struct tdls_peer_params { + uint8_t is_peer_responder; + uint8_t peer_uapsd_queue; + uint8_t peer_max_sp; + uint8_t peer_buff_sta_support; + uint8_t peer_off_chan_support; + uint8_t peer_curr_operclass; + uint8_t self_curr_operclass; + uint8_t peer_chanlen; + struct tdls_ch_params peer_chan[WLAN_MAC_MAX_SUPP_CHANNELS]; + uint8_t peer_oper_classlen; + uint8_t peer_oper_class[WLAN_MAX_SUPP_OPER_CLASSES]; + uint8_t pref_off_channum; + uint8_t pref_off_chan_bandwidth; + uint8_t opclass_for_prefoffchan; +}; + +/** + * struct tdls_peer_update_params - TDLS peer state parameters + * @vdev_id: vdev id + * @peer_macaddr: peer mac address + * @peer_cap: peer capabality + */ +struct tdls_peer_update_params { + uint32_t vdev_id; + uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; + uint32_t peer_state; + struct tdls_peer_params peer_cap; +}; + +/** + * struct tdls_chan_switch_params - channel switch parameter structure + * @vdev_id: vdev ID + * @peer_mac_addr: Peer mac address + * @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset + * @tdls_off_ch: Target Off Channel + * @oper_class: Operating class for target channel + * @is_responder: Responder or initiator + */ +struct tdls_chan_switch_params { + uint32_t vdev_id; + uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE]; + uint16_t tdls_off_ch_bw_offset; + uint8_t tdls_off_ch; + uint8_t tdls_sw_mode; + uint8_t oper_class; + uint8_t is_responder; +}; + +/** + * struct tdls_event_info - firmware tdls event + * @vdev_id: vdev id + * @peermac: peer mac address + * @message_type: message type + * @peer_reason: reason + */ +struct tdls_event_info { + uint8_t vdev_id; + struct qdf_mac_addr peermac; + uint16_t message_type; + uint32_t peer_reason; +}; + +/** + * struct tdls_event_notify - tdls event notify + * @vdev: vdev object + * @event: tdls event + */ +struct tdls_event_notify { + struct wlan_objmgr_vdev *vdev; + struct tdls_event_info event; +}; +#endif diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h new file mode 100644 index 0000000000..78454e0829 --- /dev/null +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_tgt_api.h + * + * TDLS south bound interface declaration + */ diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h new file mode 100644 index 0000000000..02d8c2beff --- /dev/null +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_ucfg_api.h + * + * TDLS north bound interface declaration + */ + +#if !defined(_WLAN_TDLS_UCFG_API_H_) +#define _WLAN_TDLS_UCFG_API_H_ + +#include +#include +#include + +/** + * ucfg_tdls_init() - TDLS module initialization API + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_init(void); + +/** + * ucfg_tdls_deinit() - TDLS module deinitilization API + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_deinit(void); + +/** + * ucfg_tdls_psoc_open() - TDLS module psoc open API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_close() - TDLS module psoc close API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_start() - TDLS module start + * @psoc: psoc object + * @req: tdls start paramets + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req); +/** + * ucfg_tdls_psoc_stop() - TDLS module stop + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); +#endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c new file mode 100644 index 0000000000..864886bb4b --- /dev/null +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_tgt_api.c + * + * TDLS south bound interface definitions + */ diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c new file mode 100644 index 0000000000..3d49c5adac --- /dev/null +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_ucfg_api.c + * + * TDLS north bound interface definitions + */ + +#include +#include "../../core/src/wlan_tdls_main.h" +#include +#include + +QDF_STATUS ucfg_tdls_init(void) +{ + QDF_STATUS status; + + tdls_notice("tdls module dispatcher init"); + status = wlan_objmgr_register_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register psoc create handler for tdls"); + return status; + } + + status = wlan_objmgr_register_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register psoc delete handler for tdls"); + goto fail_delete_psoc; + } + + status = wlan_objmgr_register_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register vdev create handler for tdls"); + goto fail_create_vdev; + } + + status = wlan_objmgr_register_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to register vdev create handler for tdls"); + goto fail_delete_vdev; + } + tdls_notice("tdls module dispatcher init done"); + + return status; +fail_delete_vdev: + wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + +fail_create_vdev: + wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + +fail_delete_psoc: + wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + + return status; +} + +QDF_STATUS ucfg_tdls_deinit(void) +{ + QDF_STATUS ret; + + tdls_notice("tdls module dispatcher deinit"); + ret = wlan_objmgr_unregister_psoc_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_create_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister psoc create handler"); + + ret = wlan_objmgr_unregister_psoc_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_psoc_obj_destroy_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister psoc delete handler"); + + ret = wlan_objmgr_unregister_vdev_create_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_create_notification, NULL); + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister vdev create handler"); + + ret = wlan_objmgr_unregister_vdev_destroy_handler(WLAN_UMAC_COMP_TDLS, + tdls_vdev_obj_destroy_notification, NULL); + + if (QDF_IS_STATUS_ERROR(ret)) + tdls_err("Failed to unregister vdev delete handler"); + + return ret; +} + +static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) +{ + uint8_t sta_idx; + + soc_obj->connected_peer_count = 0; + soc_obj->tdls_nss_switch_in_progress = false; + soc_obj->tdls_teardown_peers_cnt = 0; + soc_obj->tdls_nss_teardown_complete = false; + soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; + soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; + soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { + soc_obj->tdls_conn_info[sta_idx].sta_id = 0; + 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); + } + soc_obj->enable_tdls_connection_tracker = false; + soc_obj->tdls_external_peer_count = 0; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + + tdls_notice("tdls psoc open"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + status = tdls_global_init(soc_obj); + + return status; +} + +QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req) +{ + struct tdls_soc_priv_obj *soc_obj; + + tdls_notice("tdls psoc start"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + soc_obj->tdls_event_cb = req->tdls_event_cb; + soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; + + soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; + soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) +{ + struct tdls_soc_priv_obj *soc_obj = NULL; + + tdls_notice("tdls psoc stop"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (soc_obj == NULL) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + soc_obj->tdls_event_cb = NULL; + soc_obj->tdls_evt_cb_data = NULL; + + soc_obj->tdls_tx_cnf_cb = NULL; + soc_obj->tx_ack_cnf_cb_data = NULL; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + tdls_notice("tdls psoc close"); + + return status; +} diff --git a/dispatcher/src/wlan_tdls_utils_api.c b/dispatcher/src/wlan_tdls_utils_api.c new file mode 100644 index 0000000000..2e9b2ad43e --- /dev/null +++ b/dispatcher/src/wlan_tdls_utils_api.c @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_utils_api.c + * + * TDLS utility functions definitions + */ From c3aad438f3068a0c49c99687cac570b6eff2c946 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 13 Mar 2017 21:30:21 +0800 Subject: [PATCH 02/89] qcacmn: TDLS component: core peer operations TDLS peer operations: add, delete and update TDLS peer Change-Id: I7dba1a4b2b3b8597935db811da68ee5ba630bf4d CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 1148 +++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 174 ++++ core/src/wlan_tdls_main.c | 110 +- core/src/wlan_tdls_main.h | 93 +- core/src/wlan_tdls_peer.c | 836 +++++++++++++++ core/src/wlan_tdls_peer.h | 245 +++++ dispatcher/inc/wlan_tdls_public_structs.h | 231 ++++- dispatcher/inc/wlan_tdls_ucfg_api.h | 28 +- dispatcher/src/wlan_tdls_ucfg_api.c | 143 ++- 9 files changed, 2924 insertions(+), 84 deletions(-) create mode 100644 core/src/wlan_tdls_peer.c create mode 100644 core/src/wlan_tdls_peer.h diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 7a6aa6cb49..12dde2563d 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -21,3 +21,1151 @@ * * TDLS north bound commands implementation */ +#include +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_cmds_process.h" + +static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) +{ + return soc_obj->connected_peer_count; +} + +/** + * tdls_decrement_peer_count() - decrement connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Return: None. + */ +static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) +{ + if (soc_obj->connected_peer_count) + soc_obj->connected_peer_count--; + + tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); +} + +/** + * tdls_validate_current_mode() - check current TDL mode + * @soc_obj: TDLS soc object + * + * Return: QDF_STATUS_SUCCESS if TDLS enabled, other for disabled + */ +static QDF_STATUS tdls_validate_current_mode(struct tdls_soc_priv_obj *soc_obj) +{ + if (soc_obj->tdls_current_mode == TDLS_SUPPORT_DISABLED || + soc_obj->tdls_current_mode == TDLS_SUPPORT_SUSPENDED) { + tdls_err("TDLS mode disabled OR not enabled, current mode %d", + soc_obj->tdls_current_mode); + return QDF_STATUS_E_NOSUPPORT; + } + return QDF_STATUS_SUCCESS; +} + +static char *tdls_get_ser_cmd_str(enum wlan_serialization_cmd_type type) +{ + switch (type) { + case WLAN_SER_CMD_TDLS_ADD_PEER: + return "TDLS_ADD_PEER_CMD"; + case WLAN_SER_CMD_TDLS_DEL_PEER: + return "TDLS_DEL_PEER_CMD"; + case WLAN_SER_CMD_TDLS_SEND_MGMT: + return "TDLS_SEND_MGMT_CMD"; + default: + return "UNKNOWN"; + } +} + +static void +tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type type) +{ + struct wlan_serialization_queued_cmd_info cmd = {0}; + + cmd.cmd_type = type; + cmd.cmd_id = 0; + cmd.vdev = vdev; + + tdls_debug("release %s", tdls_get_ser_cmd_str(type)); + /* Inform serialization for command completion */ + wlan_serialization_remove_cmd(&cmd); +} + +/** + * tdls_pe_add_peer() - send TDLS add peer request to PE + * @req: TDL add peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) +{ + struct tdls_add_sta_req *addstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + addstareq = qdf_mem_malloc(sizeof(*addstareq)); + if (!addstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + addstareq->tdls_oper = TDLS_OPER_ADD; + addstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + addstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(addstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, + QDF_MAC_ADDR_SIZE); + + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + msg.type = soc_obj->tdls_add_sta_req; + msg.bodyptr = addstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to add peer"); + goto error; + } + return status; +error: + qdf_mem_free(addstareq); + return status; +} + +/** + * tdls_pe_del_peer() - send TDLS delete peer request to PE + * @req: TDLS delete peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) +{ + struct tdls_del_sta_req *delstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + delstareq = qdf_mem_malloc(sizeof(*delstareq)); + if (!delstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + delstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + delstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(delstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, + QDF_MAC_ADDR_SIZE); + + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); + msg.type = soc_obj->tdls_del_sta_req; + msg.bodyptr = delstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to del peer"); + goto error; + } + return status; +error: + qdf_mem_free(delstareq); + return status; +} + +/** + * tdls_pe_update_peer() - send TDLS update peer request to PE + * @req: TDLS update peer request + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) +{ + struct tdls_add_sta_req *addstareq; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct scheduler_msg msg = {0,}; + struct tdls_update_peer_params *update_peer; + QDF_STATUS status; + + addstareq = qdf_mem_malloc(sizeof(*addstareq)); + if (!addstareq) { + tdls_err("allocate failed"); + return QDF_STATUS_E_NOMEM; + } + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + update_peer = &req->update_peer_req; + + addstareq->tdls_oper = TDLS_OPER_UPDATE; + addstareq->transaction_id = 0; + + wlan_vdev_obj_lock(vdev); + addstareq->session_id = wlan_vdev_get_id(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + if (!peer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + status = QDF_STATUS_E_INVAL; + goto error; + } + wlan_vdev_obj_unlock(vdev); + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get bss peer"); + goto error; + } + wlan_peer_obj_lock(peer); + qdf_mem_copy(addstareq->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + wlan_peer_obj_unlock(peer); + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID); + qdf_mem_copy(addstareq->peermac.bytes, update_peer->peer_addr, + QDF_MAC_ADDR_SIZE); + addstareq->capability = update_peer->capability; + addstareq->uapsd_queues = update_peer->uapsd_queues; + addstareq->max_sp = update_peer->max_sp; + + qdf_mem_copy(addstareq->extn_capability, + update_peer->extn_capability, WLAN_MAC_MAX_EXTN_CAP); + addstareq->htcap_present = update_peer->htcap_present; + qdf_mem_copy(&addstareq->ht_cap, + &update_peer->ht_cap, + sizeof(update_peer->ht_cap)); + addstareq->vhtcap_present = update_peer->vhtcap_present; + qdf_mem_copy(&addstareq->vht_cap, + &update_peer->vht_cap, + sizeof(update_peer->vht_cap)); + addstareq->supported_rates_length = update_peer->supported_rates_len; + qdf_mem_copy(&addstareq->supported_rates, + update_peer->supported_rates, + update_peer->supported_rates_len); + tdls_debug("for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); + + msg.type = soc_obj->tdls_add_sta_req; + msg.bodyptr = addstareq; + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("fail to post pe msg to update peer"); + goto error; + } + return status; +error: + qdf_mem_free(addstareq); + return status; +} + +static QDF_STATUS +tdls_internal_add_peer_rsp(struct tdls_add_peer_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + struct tdls_osif_indication ind; + QDF_STATUS ret; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(ret)) { + tdls_err("can't get vdev object"); + return ret; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = status; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS +tdls_internal_update_peer_rsp(struct tdls_update_peer_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS ret; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + ret = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(ret)) { + tdls_err("can't get vdev object"); + return ret; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = status; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_internal_del_peer_rsp(struct tdls_oper_request *req) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + return QDF_STATUS_E_INVAL; + } + vdev = req->vdev; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev object"); + return status; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = req->vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DEL_PEER, &ind); + } + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *peer; + uint16_t curr_tdls_peers; + const uint8_t *mac; + struct tdls_osif_indication ind; + + if (!req->vdev) { + tdls_err("vdev null when add tdls peer"); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + mac = req->add_peer_req.peer_addr; + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + return QDF_STATUS_E_INVAL; + } + status = tdls_validate_current_mode(soc_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto addrsp; + + peer = tdls_get_peer(vdev_obj, mac); + if (!peer) { + tdls_err("peer: " QDF_MAC_ADDRESS_STR " not exist. invalid", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto addrsp; + } + + /* in add station, we accept existing valid sta_id if there is */ + if ((peer->link_status > TDLS_LINK_CONNECTING) || + (TDLS_STA_INDEX_CHECK((peer->sta_id)))) { + tdls_notice("link_status %d sta_id %d add peer ignored", + peer->link_status, peer->sta_id); + status = QDF_STATUS_SUCCESS; + goto addrsp; + } + + /* when others are on-going, we want to change link_status to idle */ + if (tdls_is_progress(vdev_obj, mac, true)) { + tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + /* first to check if we reached to maximum supported TDLS peer. */ + curr_tdls_peers = tdls_get_connected_peer(soc_obj); + if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { + tdls_err(QDF_MAC_ADDRESS_STR + " Request declined. Current %d, Max allowed %d.", + QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + soc_obj->max_num_tdls_sta); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + tdls_set_peer_link_status(peer, + TDLS_LINK_CONNECTING, TDLS_LINK_SUCCESS); + + status = tdls_pe_add_peer(req); + if (QDF_IS_STATUS_ERROR(status)) + goto setlink; + + return QDF_STATUS_SUCCESS; + +setlink: + tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); +addrsp: + if (soc_obj->tdls_event_cb) { + ind.status = status; + ind.vdev = req->vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + + return QDF_STATUS_E_PERM; +} + +static QDF_STATUS +tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_add_peer_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_add_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & vdev reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_add_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.vdev = vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + goto error; + } + + return status; +error: + status = tdls_internal_add_peer_rsp(req, QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + return status; +} + +static QDF_STATUS +tdls_activate_update_peer(struct tdls_update_peer_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev; + struct tdls_peer *curr_peer; + uint16_t curr_tdls_peers; + const uint8_t *mac; + struct tdls_update_peer_params *update_peer; + struct tdls_osif_indication ind; + + if (!req->vdev) { + tdls_err("vdev object NULL when add TDLS peer"); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + mac = req->update_peer_req.peer_addr; + vdev = req->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + return QDF_STATUS_E_INVAL; + } + + status = tdls_validate_current_mode(soc_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto updatersp; + + curr_peer = tdls_get_peer(vdev_obj, mac); + if (!curr_peer) { + tdls_err(QDF_MAC_ADDRESS_STR " not exist. return invalid", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto updatersp; + } + + /* in change station, we accept only when sta_id is valid */ + if (curr_peer->link_status > TDLS_LINK_CONNECTING || + !(TDLS_STA_INDEX_CHECK(curr_peer->sta_id))) { + tdls_err(QDF_MAC_ADDRESS_STR " link %d. sta %d. update peer %s", + QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, + curr_peer->sta_id, + (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? "ignored" + : "declined"); + status = (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? + QDF_STATUS_SUCCESS : QDF_STATUS_E_PERM; + goto updatersp; + } + + /* when others are on-going, we want to change link_status to idle */ + if (tdls_is_progress(vdev_obj, mac, true)) { + tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_PERM; + goto setlink; + } + + curr_tdls_peers = tdls_get_connected_peer(soc_obj); + if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { + tdls_err(QDF_MAC_ADDRESS_STR + " Request declined. Current: %d, Max allowed: %d.", + QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, + soc_obj->max_num_tdls_sta); + status = QDF_STATUS_E_PERM; + goto setlink; + } + update_peer = &req->update_peer_req; + + if (update_peer->htcap_present) + curr_peer->spatial_streams = update_peer->ht_cap.mcsset[1]; + + tdls_set_peer_caps(vdev_obj, mac, &req->update_peer_req); + status = tdls_pe_update_peer(req); + if (QDF_IS_STATUS_ERROR(status)) + goto setlink; + + return QDF_STATUS_SUCCESS; + +setlink: + tdls_set_link_status(vdev_obj, mac, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); +updatersp: + if (soc_obj->tdls_event_cb) { + ind.status = status; + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + + return QDF_STATUS_E_PERM; +} + +static QDF_STATUS +tdls_update_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_update_peer_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_update_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & release reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_FAILURE; + goto error; + } + + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_ADD_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_update_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.vdev = req->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_update_peer_rsp(req, + QDF_STATUS_E_FAILURE); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +error: + status = tdls_internal_update_peer_rsp(req, QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + return status; +} + +static QDF_STATUS tdls_activate_del_peer(struct tdls_oper_request *req) +{ + struct tdls_del_peer_request request = {0,}; + + request.vdev = req->vdev; + request.del_peer_req.peer_addr = req->peer_addr; + + return tdls_pe_del_peer(&request); +} + +static QDF_STATUS +tdls_del_peer_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_oper_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("cmd: %p, reason: %d", cmd, reason); + return QDF_STATUS_E_NULL_VALUE; + } + + req = cmd->umac_cmd; + tdls_debug("reason: %d, req %p", reason, req); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list + */ + status = tdls_activate_del_peer(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + /* command removed from pending list. + * notify os interface the status + */ + status = tdls_internal_del_peer_rsp(req); + break; + + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* active command time out. */ + status = tdls_internal_del_peer_rsp(req); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release memory & vdev reference count + */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) +{ + struct wlan_serialization_command cmd = {0,}; + enum wlan_serialization_status ser_cmd_status; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + vdev = req->vdev; + cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_del_peer_serialize_callback; + cmd.umac_cmd = req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; + cmd.vdev = vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list. Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* notify os interface about internal error*/ + status = tdls_internal_del_peer_rsp(req); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + /* cmd can't be serviced. + * release tdls_add_peer_request memory + */ + qdf_mem_free(req); + break; + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +error: + status = tdls_internal_del_peer_rsp(req); + qdf_mem_free(req); + return status; +} + +/** + * tdls_process_add_peer_rsp() - handle response for update TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_update_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_soc_priv_obj *soc_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + if (!psoc) { + tdls_err("psoc is NULL"); + QDF_ASSERT(0); + return QDF_STATUS_E_FAILURE; + } + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (soc_obj && soc_obj->tdls_event_cb) { + ind.status = rsp->status_code; + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} + +/** + * tdls_process_add_peer_rsp() - handle response for add TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + uint8_t sta_idx; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj = NULL; + struct tdls_conn_info *conn_rec; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + if (rsp->status_code) { + tdls_err("add sta failed. status code(=%d)", rsp->status_code); + status = QDF_STATUS_E_FAILURE; + } else { + conn_rec = soc_obj->tdls_conn_info; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; + sta_idx++) { + if (0 == conn_rec[sta_idx].sta_id) { + conn_rec[sta_idx].session_id = rsp->session_id; + conn_rec[sta_idx].sta_id = rsp->sta_id; + qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, + &rsp->peermac); + tdls_warn("TDLS: STA IDX at %d is %d of mac " + QDF_MAC_ADDRESS_STR, sta_idx, + rsp->sta_id, QDF_MAC_ADDR_ARRAY + (rsp->peermac.bytes)); + break; + } + } + + if (sta_idx < soc_obj->max_num_tdls_sta) { + status = tdls_set_sta_id(vdev_obj, rsp->peermac.bytes, + rsp->sta_id); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set staid failed"); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + + tdls_set_signature(vdev_obj, rsp->peermac.bytes, + rsp->ucast_sig); + } else { + status = QDF_STATUS_E_FAILURE; + } + } + +cmddone: + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_ADD_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = rsp->status_code; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ADD_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} + +QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp) +{ + tdls_debug("peer oper %d", rsp->tdls_oper); + + if (rsp->tdls_oper == TDLS_OPER_ADD) + return tdls_add_peer_rsp(rsp); + else if (rsp->tdls_oper == TDLS_OPER_UPDATE) + return tdls_update_peer_rsp(rsp); + + return QDF_STATUS_E_INVAL; +} + +QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) +{ + uint8_t sta_idx, id; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj = NULL; + struct tdls_conn_info *conn_rec; + struct tdls_peer *curr_peer = NULL; + const uint8_t *macaddr; + struct tdls_osif_indication ind; + + tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDRESS_STR, + rsp->session_id, QDF_MAC_ADDR_ARRAY(rsp->peermac.bytes)); + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev: %d", rsp->session_id); + status = QDF_STATUS_E_INVAL; + goto error; + } + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + status = QDF_STATUS_E_FAILURE; + goto cmddone; + } + + conn_rec = soc_obj->tdls_conn_info; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { + if (conn_rec[sta_idx].session_id != rsp->session_id || + conn_rec[sta_idx].sta_id != rsp->sta_id) + continue; + + macaddr = rsp->peermac.bytes; + tdls_warn("TDLS: del STA IDX = %x", rsp->sta_id); + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (curr_peer) { + tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", + QDF_MAC_ADDR_ARRAY(macaddr), + curr_peer->link_status); + wlan_vdev_obj_lock(vdev); + id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + if (TDLS_IS_CONNECTED(curr_peer)) { + soc_obj->tdls_dereg_tl_peer( + soc_obj->tdls_tl_peer_data, + id, curr_peer->sta_id); + tdls_decrement_peer_count(soc_obj); + } else if (TDLS_LINK_CONNECTING == + curr_peer->link_status) { + soc_obj->tdls_dereg_tl_peer( + soc_obj->tdls_tl_peer_data, + id, curr_peer->sta_id); + } + } + tdls_reset_peer(vdev_obj, macaddr); + conn_rec[sta_idx].sta_id = 0; + conn_rec[sta_idx].session_id = 0xff; + qdf_mem_zero(&conn_rec[sta_idx].peer_mac, + QDF_MAC_ADDR_SIZE); + + status = QDF_STATUS_SUCCESS; + break; + } + macaddr = rsp->peermac.bytes; + if (!curr_peer) { + curr_peer = tdls_find_peer(vdev_obj, macaddr); + + if (curr_peer) + tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, + (curr_peer->link_status == + TDLS_LINK_TEARING) ? + TDLS_LINK_UNSPECIFIED : + TDLS_LINK_DROPPED_BY_REMOTE); + } + +cmddone: + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_DEL_PEER); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +error: + + if (soc_obj && soc_obj->tdls_event_cb) { + ind.vdev = vdev; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DEL_PEER, &ind); + } + qdf_mem_free(rsp); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index a90931846a..253403f550 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -21,3 +21,177 @@ * * TDLS north bound commands include file */ + +#ifndef _WLAN_TDLS_CMDS_PROCESS_H_ +#define _WLAN_TDLS_CMDS_PROCESS_H_ + +/** + * enum tdls_add_oper - add peer type + * @TDLS_OPER_NONE: none + * @TDLS_OPER_ADD: add new peer + * @TDLS_OPER_UPDATE: used to update peer + */ +enum tdls_add_oper { + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +}; + +/** + * struct tdls_add_sta_req - TDLS request struct TDLS module --> PE + * same as struct tSirTdlsAddStaReq; + * @message_type: eWNI_SME_TDLS_ADD_STA_REQ + * @length: message length + * @session_id: session id + * @transaction_id: transaction id for cmd + * @bssid: bssid + * @tdls_oper: add peer type + * @peermac: MAC address for TDLS peer + * @capability: mac capability as sSirMacCapabilityInfo + * @extn_capability: extent capability + * @supported_rates_length: rates length + * @supported_rates: supported rates + * @htcap_present: ht capability present + * @ht_cap: ht capability + * @vhtcap_present: vht capability present + * @vht_cap: vht capability + * @uapsd_queues: uapsd queue as sSirMacQosInfoStation + * @max_sp: maximum service period + */ +struct tdls_add_sta_req { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + struct qdf_mac_addr bssid; + enum tdls_add_oper tdls_oper; + struct qdf_mac_addr peermac; + uint16_t capability; + uint8_t extn_capability[WLAN_MAC_MAX_EXTN_CAP]; + uint8_t supported_rates_length; + uint8_t supported_rates[WLAN_MAC_MAX_SUPP_RATES]; + uint8_t htcap_present; + struct htcap_cmn_ie ht_cap; + uint8_t vhtcap_present; + struct vhtcap vht_cap; + uint8_t uapsd_queues; + uint8_t max_sp; +}; + +/** + * struct tdls_add_sta_rsp - TDLS Response struct PE --> TDLS module + * same as struct sSirTdlsAddStaRsp + * @message_type: message type eWNI_SME_TDLS_ADD_STA_RSP + * @length: message length + * @status_code: status code as tSirResultCodes + * @peermac: MAC address of the TDLS peer + * @session_id: session id + * @sta_id: sta id + * @sta_type: sta type + * @ucast_sig: unicast signature + * @bcast_sig: broadcast signature + * @tdls_oper: add peer type + * @psoc: soc object + */ +struct tdls_add_sta_rsp { + uint16_t message_type; + uint16_t length; + QDF_STATUS status_code; + struct qdf_mac_addr peermac; + uint8_t session_id; + uint16_t sta_id; + uint16_t sta_type; + uint8_t ucast_sig; + uint8_t bcast_sig; + enum tdls_add_oper tdls_oper; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * struct tdls_del_sta_req - TDLS Request struct TDLS module --> PE + * same as sSirTdlsDelStaReq + * @message_type: message type eWNI_SME_TDLS_DEL_STA_REQ + * @length: message length + * @session_id: session id + * @transaction_id: transaction id for cmd + * @bssid: bssid + * @peermac: MAC address of the TDLS peer + */ +struct tdls_del_sta_req { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + struct qdf_mac_addr bssid; + struct qdf_mac_addr peermac; +}; + +/** + * struct tdls_del_sta_rsp - TDLS Response struct PE --> TDLS module + * same as sSirTdlsDelStaRsp + * @message_type: message type eWNI_SME_TDLS_DEL_STA_RSP + * @length: message length + * @session_id: session id + * @status_code: status code as tSirResultCodes + * @peermac: MAC address of the TDLS peer + * @sta_id: sta id + * @psoc: soc object + */ +struct tdls_del_sta_rsp { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + QDF_STATUS status_code; + struct qdf_mac_addr peermac; + uint16_t sta_id; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * tdls_process_add_peer() - add TDLS peer + * @req: TDLS add peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req); + +/** + * tdls_process_del_peer() - del TDLS peer + * @req: TDLS del peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req); + +/** + * tdls_process_update_peer() - update TDLS peer + * @req: TDLS update peer request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req); + +/** + * tdls_pe_del_peer() - send TDLS delete peer request to PE + * @req: TDLS delete peer request + * + * Return: QDF status + */ +QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req); + +/** + * tdls_process_add_peer_rsp() - handle response for add or update TDLS peer + * @rsp: TDLS add peer response + * + * Return: QDF status + */ +QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); + +/** + * tdls_process_add_peer_rsp() - handle response for delete TDLS peer + * @rsp: TDLS delete peer response + * + * Return: QDF status + */ +QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp); +#endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index eef8915fb3..ab4a5e5c9a 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -23,6 +23,8 @@ */ #include "wlan_tdls_main.h" +#include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_peer.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -31,7 +33,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, struct tdls_soc_priv_obj *tdls_soc_obj; tdls_soc_obj = qdf_mem_malloc(sizeof(*tdls_soc_obj)); - if (tdls_soc_obj == NULL) { + if (!tdls_soc_obj) { tdls_err("Failed to allocate memory for tdls object"); return QDF_STATUS_E_NOMEM; } @@ -61,7 +63,7 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (tdls_soc_obj == NULL) { + if (!tdls_soc_obj) { tdls_err("Failed to get tdls obj in psoc"); return QDF_STATUS_E_FAILURE; } @@ -78,19 +80,53 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, return status; } -static void tdls_vdev_init(struct tdls_vdev_priv_obj *vdev) +static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) { uint8_t i; + struct tdls_config_params *config; + struct tdls_user_config *user_config; + struct tdls_soc_priv_obj *soc_obj; - for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { - qdf_list_create(&vdev->peer_list[i], - WLAN_TDLS_PEER_SUB_LIST_SIZE); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("tdls soc obj NULL"); + return QDF_STATUS_E_FAILURE; } - qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev); - qdf_mc_timer_init(&vdev->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev); + config = &vdev_obj->threshold_config; + user_config = &soc_obj->tdls_configs; + config->tx_period_t = user_config->tdls_tx_states_period; + config->tx_packet_n = user_config->tdls_tx_pkt_threshold; + config->discovery_tries_n = user_config->tdls_max_discovery_attempt; + config->idle_timeout_t = user_config->tdls_idle_timeout; + config->idle_packet_n = user_config->tdls_idle_pkt_threshold; + config->rssi_trigger_threshold = + user_config->tdls_rssi_trigger_threshold; + config->rssi_teardown_threshold = + user_config->tdls_rssi_teardown_threshold; + config->rssi_delta = user_config->tdls_rssi_delta; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + qdf_list_create(&vdev_obj->peer_list[i], + WLAN_TDLS_PEER_SUB_LIST_SIZE); + } + qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, + NULL, vdev_obj); + qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, + NULL, vdev_obj); + return QDF_STATUS_SUCCESS; +} + +static void tdls_vdev_deinit(struct tdls_vdev_priv_obj *vdev_obj) +{ + qdf_mc_timer_stop(&vdev_obj->peer_update_timer); + qdf_mc_timer_stop(&vdev_obj->peer_discovery_timer); + + qdf_mc_timer_destroy(&vdev_obj->peer_update_timer); + qdf_mc_timer_destroy(&vdev_obj->peer_discovery_timer); + + tdls_peer_idle_timers_destroy(vdev_obj); + tdls_free_peer_list(vdev_obj); } QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, @@ -107,14 +143,11 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, /* TODO: Add concurrency check */ tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); - if (tdls_vdev_obj == NULL) { + if (!tdls_vdev_obj) { tdls_err("Failed to allocate memory for tdls vdev object"); return QDF_STATUS_E_NOMEM; } - tdls_vdev_obj->vdev = vdev; - tdls_vdev_init(tdls_vdev_obj); - status = wlan_objmgr_vdev_component_obj_attach(vdev, WLAN_UMAC_COMP_TDLS, (void *)tdls_vdev_obj, @@ -122,10 +155,15 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach vdev tdls component"); qdf_mem_free(tdls_vdev_obj); + goto out; } + tdls_vdev_obj->vdev = vdev; + status = tdls_vdev_init(tdls_vdev_obj); + if (QDF_IS_STATUS_ERROR(status)) + goto out; tdls_notice("tdls object attach to vdev successfully"); - +out: return status; } @@ -142,7 +180,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); - if (tdls_vdev_obj == NULL) { + if (!tdls_vdev_obj) { tdls_err("Failed to get tdls vdev object"); return QDF_STATUS_E_FAILURE; } @@ -153,7 +191,47 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) tdls_err("Failed to detach vdev tdls component"); + tdls_vdev_deinit(tdls_vdev_obj); qdf_mem_free(tdls_vdev_obj); return status; } + +QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: 0x%p, bodyptr: 0x%p", msg, msg->bodyptr); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + switch (msg->type) { + case TDLS_CMD_TX_ACTION: + break; + case TDLS_CMD_ADD_STA: + tdls_process_add_peer(msg->bodyptr); + break; + case TDLS_CMD_CHANGE_STA: + tdls_process_update_peer(msg->bodyptr); + break; + case TDLS_CMD_ENABLE_LINK: + break; + case TDLS_CMD_DISABLE_LINK: + tdls_process_del_peer(msg->bodyptr); + break; + case TDLS_CMD_CONFIG_FORCE_PEER: + break; + case TDLS_CMD_REMOVE_FORCE_PEER: + break; + case TDLS_CMD_STATS_UPDATE: + break; + case TDLS_CMD_CONFIG_UPDATE: + break; + default: + break; + } + + return status; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b85c74cc5f..4d4d5f2bbd 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -39,6 +39,17 @@ #define ENA_TDLS_BUFFER_STA (1 << 1) /* TDLS Buffer STA support */ #define ENA_TDLS_SLEEP_STA (1 << 2) /* TDLS Sleep STA support */ +#define BW_20_OFFSET_BIT 0 +#define BW_40_OFFSET_BIT 1 +#define BW_80_OFFSET_BIT 2 +#define BW_160_OFFSET_BIT 3 + +#define TDLS_SEC_OFFCHAN_OFFSET_0 0 +#define TDLS_SEC_OFFCHAN_OFFSET_40PLUS 40 +#define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40) +#define TDLS_SEC_OFFCHAN_OFFSET_80 80 +#define TDLS_SEC_OFFCHAN_OFFSET_160 160 + #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) #define tdls_logfl(level, format, args...) \ @@ -163,13 +174,20 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data + * @tdls_reg_tl_peer: callback to register the TDLS peer with TL + * @tdls_dereg_tl_peer: callback to unregister the TDLS peer + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support + * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value + * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value + * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value + * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value */ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; - enum tdls_support_mode tdls_current_mode; - enum tdls_support_mode tdls_user_config_mode; + enum tdls_feature_mode tdls_current_mode; + enum tdls_feature_mode tdls_user_config_mode; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; uint16_t max_num_tdls_sta; @@ -188,8 +206,15 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; + tdls_register_tl_peer_callback tdls_reg_tl_peer; + tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; + uint16_t tdls_send_mgmt_req; + uint16_t tdls_add_sta_req; + uint16_t tdls_del_sta_req; + uint16_t tdls_update_peer_state; }; /** @@ -225,6 +250,12 @@ struct tdls_vdev_priv_obj { qdf_list_t tx_queue; }; +/** + * struct tdls_peer_mlme_info - tdls peer mlme info + **/ +struct tdls_peer_mlme_info { +}; + /** * struct tdls_peer - tdls peer data * @node: node @@ -266,7 +297,7 @@ struct tdls_peer { uint16_t sta_id; int8_t rssi; enum tdls_peer_capab tdls_support; - enum tdls_link_status link_status; + enum tdls_link_state link_status; uint8_t signature; uint8_t is_responder; uint8_t discovery_processed; @@ -288,9 +319,10 @@ struct tdls_peer { qdf_mc_timer_t peer_idle_timer; bool is_peer_idle_timer_initialised; uint8_t spatial_streams; - enum tdls_link_reason reason; + enum tdls_link_state_reason reason; tdls_state_change_callback state_change_notification; uint8_t qos; + struct tdls_peer_mlme_info *tdls_info; }; /** @@ -302,12 +334,29 @@ struct tdls_peer { static inline struct tdls_soc_priv_obj * wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) { - struct wlan_objmgr_psoc *psoc = - wlan_pdev_get_psoc(wlan_vdev_get_pdev(vdev)); + struct wlan_objmgr_psoc *psoc; + struct tdls_soc_priv_obj *soc_obj; - return (struct tdls_soc_priv_obj *) + if (!vdev) { + tdls_err("NULL vdev"); + return NULL; + } + + wlan_vdev_obj_lock(vdev); + psoc = wlan_vdev_get_psoc(vdev); + wlan_vdev_obj_unlock(vdev); + if (!psoc) { + tdls_err("can't get psoc"); + return NULL; + } + + wlan_psoc_obj_lock(psoc); + soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); + wlan_psoc_obj_unlock(psoc); + + return soc_obj; } /** @@ -319,9 +368,18 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) static inline struct tdls_soc_priv_obj * wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) { - return (struct tdls_soc_priv_obj *) + struct tdls_soc_priv_obj *soc_obj; + if (!psoc) { + tdls_err("NULL psoc"); + return NULL; + } + wlan_psoc_obj_lock(psoc); + soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); + wlan_psoc_obj_unlock(psoc); + + return soc_obj; } /** @@ -333,22 +391,33 @@ wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) static inline struct tdls_vdev_priv_obj * wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) { - return (struct tdls_vdev_priv_obj *) + struct tdls_vdev_priv_obj *vdev_obj; + + if (!vdev) { + tdls_err("NULL vdev"); + return NULL; + } + + wlan_vdev_obj_lock(vdev); + vdev_obj = (struct tdls_vdev_priv_obj *) wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); + wlan_vdev_obj_unlock(vdev); + + return vdev_obj; } /** * tdls_set_link_status - tdls set link status * @vdev: vdev object * @mac: mac address of tdls peer - * @link_status: tdls link status + * @link_state: tdls link state * @link_reason: reason */ void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev, const uint8_t *mac, - enum tdls_link_status link_status, - enum tdls_link_reason link_reason); + enum tdls_link_state link_state, + enum tdls_link_state_reason link_reason); /** * tdls_psoc_obj_create_notification() - tdls psoc create notification handler * @psoc: psoc object diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c new file mode 100644 index 0000000000..a89736fb95 --- /dev/null +++ b/core/src/wlan_tdls_peer.c @@ -0,0 +1,836 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_peer.c + * + * TDLS peer basic operations + */ +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include +#include +#include + +static uint8_t calculate_hash_key(const uint8_t *macaddr) +{ + uint8_t i, key; + + for (i = 0, key = 0; i < 6; i++) + key ^= macaddr[i]; + + return key % WLAN_TDLS_PEER_LIST_SIZE; +} + +struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + uint8_t key; + QDF_STATUS status; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + + key = calculate_hash_key(macaddr); + head = &vdev_obj->peer_list[key]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (WLAN_ADDR_EQ(&peer->peer_mac, macaddr) + == QDF_STATUS_SUCCESS) { + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + + tdls_debug("no tdls peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + return NULL; +} + +/** + * tdls_find_peer_handler() - helper function for tdls_find_all_peer + * @psoc: soc object + * @obj: vdev object + * @arg: used to keep search peer parameters + * + * Return: None. + */ +static void +tdls_find_peer_handler(struct wlan_objmgr_psoc *psoc, void *obj, void *arg) +{ + struct wlan_objmgr_vdev *vdev = obj; + struct tdls_search_peer_param *tdls_param = arg; + struct tdls_vdev_priv_obj *vdev_obj; + + if (tdls_param->peer) + return; + + if (!vdev) { + tdls_err("invalid vdev"); + return; + } + + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return; + + vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (!vdev_obj) + return; + + tdls_param->peer = tdls_find_peer(vdev_obj, tdls_param->macaddr); +} + +struct tdls_peer * +tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr) +{ + struct tdls_search_peer_param tdls_search_param; + struct wlan_objmgr_psoc *psoc; + + if (!soc_obj) { + tdls_err("tdls soc object is NULL"); + return NULL; + } + + psoc = soc_obj->soc; + if (!psoc) { + tdls_err("psoc is NULL"); + return NULL; + } + tdls_search_param.macaddr = macaddr; + tdls_search_param.peer = NULL; + + wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, + tdls_find_peer_handler, + &tdls_search_param, 0, WLAN_TDLS_NB_ID); + + return tdls_search_param.peer; +} + +static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, + uint8_t bw_offset) +{ + char country[REG_ALPHA2_LEN + 1]; + QDF_STATUS status; + + if (!psoc) { + tdls_err("psoc is NULL"); + return 0; + } + + status = wlan_reg_read_default_country(psoc, country); + if (QDF_IS_STATUS_ERROR(status)) + return 0; + + return wlan_reg_dmn_get_opclass_from_channel(country, channel, + bw_offset); +} + +/** + * tdls_add_peer() - add TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * Allocate memory for the new peer, and add it to hash table. + * + * Return: new added TDLS peer, NULL if failed. + */ +static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + uint8_t key = 0; + qdf_list_t *head; + + peer = qdf_mem_malloc(sizeof(*peer)); + if (!peer) { + tdls_err("add tdls peer malloc memory failed!"); + return NULL; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL tdls soc object"); + return NULL; + } + + key = calculate_hash_key(macaddr); + head = &vdev_obj->peer_list[key]; + + qdf_mem_copy(&peer->peer_mac, macaddr, sizeof(peer->peer_mac)); + peer->vdev_priv = vdev_obj; + + peer->pref_off_chan_num = + soc_obj->tdls_configs.tdls_pre_off_chan_num; + peer->op_class_for_pref_off_chan = + tdls_find_opclass(soc_obj->soc, + peer->pref_off_chan_num, + soc_obj->tdls_configs.tdls_pre_off_chan_bw); + + qdf_list_insert_back(head, &peer->node); + + tdls_debug("add tdls peer: " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + return peer; +} + +struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) + peer = tdls_add_peer(vdev_obj, macaddr); + + return peer; +} + +static struct tdls_peer * +tdls_find_progress_peer_in_list(qdf_list_t *head, + const uint8_t *macaddr, uint8_t skip_self) +{ + QDF_STATUS status; + struct tdls_peer *peer; + qdf_list_node_t *p_node; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (skip_self && macaddr && + WLAN_ADDR_EQ(&peer->peer_mac, macaddr) + == QDF_STATUS_SUCCESS) { + status = qdf_list_peek_next(head, p_node, &p_node); + continue; + } else if (TDLS_LINK_CONNECTING == peer->link_status) { + tdls_debug(QDF_MAC_ADDRESS_STR " TDLS_LINK_CONNECTING", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + + return NULL; +} + +/** + * tdls_find_progress_peer() - find the peer with ongoing TDLS progress + * on present vdev + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer, if NULL check for all the peer list + * @skip_self: If true, skip this macaddr. Otherwise, check all the peer list. + * if macaddr is NULL, this argument is ignored, and check for all + * the peer list. + * + * Return: Pointer to tdls_peer if TDLS is ongoing. Otherwise return NULL. + */ +static struct tdls_peer * +tdls_find_progress_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self) +{ + uint8_t i; + struct tdls_peer *peer; + qdf_list_t *head; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + peer = tdls_find_progress_peer_in_list(head, macaddr, + skip_self); + if (peer) + return peer; + } + + return NULL; +} + +/** + * tdls_find_progress_peer_handler() - helper function for tdls_is_progress + * @psoc: soc object + * @obj: vdev object + * @arg: used to keep search peer parameters + * + * Return: None. + */ +static void +tdls_find_progress_peer_handler(struct wlan_objmgr_psoc *psoc, + void *obj, void *arg) +{ + struct wlan_objmgr_vdev *vdev = obj; + struct tdls_search_progress_param *tdls_progress = arg; + struct tdls_vdev_priv_obj *vdev_obj; + + if (tdls_progress->peer) + return; + + if (!vdev) { + tdls_err("invalid vdev"); + return; + } + + if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && + wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) + return; + + vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + + tdls_progress->peer = tdls_find_progress_peer(vdev_obj, + tdls_progress->macaddr, + tdls_progress->skip_self); +} + +struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self) +{ + struct tdls_search_progress_param tdls_progress; + struct wlan_objmgr_psoc *psoc; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + wlan_vdev_obj_lock(vdev_obj->vdev); + psoc = wlan_vdev_get_psoc(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + if (!psoc) { + tdls_err("invalid psoc"); + return NULL; + } + tdls_progress.macaddr = macaddr; + tdls_progress.skip_self = skip_self; + tdls_progress.peer = NULL; + + wlan_objmgr_iterate_obj_list(psoc, WLAN_VDEV_OP, + tdls_find_progress_peer_handler, + &tdls_progress, 0, WLAN_TDLS_NB_ID); + + return tdls_progress.peer; +} + +struct tdls_peer * +tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!vdev_obj) { + tdls_err("invalid tdls vdev object"); + return NULL; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + + if (peer && TDLS_LINK_CONNECTED == peer->link_status) { + tdls_debug(QDF_MAC_ADDRESS_STR + " TDLS_LINK_CONNECTED", + QDF_MAC_ADDR_ARRAY( + peer->peer_mac.bytes)); + return peer; + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + return NULL; +} + +/** + * tdls_determine_channel_opclass() - determine channel and opclass + * @soc_obj: TDLS soc object + * @vdev_obj: TDLS vdev object + * @peer: TDLS peer + * @channel: pointer to channel + * @opclass: pinter to opclass + * + * Function determines the channel and operating class + * + * Return: None. + */ +static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, + struct tdls_vdev_priv_obj *vdev_obj, + struct tdls_peer *peer, + uint32_t *channel, uint32_t *opclass) +{ + uint32_t vdev_id; + enum tQDF_ADAPTER_MODE opmode; + /* + * If tdls offchannel is not enabled then we provide base channel + * and in that case pass opclass as 0 since opclass is mainly needed + * for offchannel cases. + */ + if (!(TDLS_IS_OFF_CHANNEL_ENABLED( + soc_obj->tdls_configs.tdls_feature_flags)) || + soc_obj->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH) { + wlan_vdev_obj_lock(vdev_obj->vdev); + vdev_id = wlan_vdev_get_id(vdev_obj->vdev); + opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + + *channel = policy_mgr_get_channel(soc_obj->soc, + opmode, &vdev_id); + *opclass = 0; + } else { + *channel = peer->pref_off_chan_num; + *opclass = peer->op_class_for_pref_off_chan; + } + tdls_debug("channel:%d opclass:%d", *channel, *opclass); +} + +/** + * tdls_get_wifi_hal_state() - get TDLS wifi hal state on current peer + * @peer: TDLS peer + * @state: output parameter to store the TDLS wifi hal state + * @reason: output parameter to store the reason of the current peer + * + * Return: None. + */ +static void tdls_get_wifi_hal_state(struct tdls_peer *peer, uint32_t *state, + int32_t *reason) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_soc_priv_obj *soc_obj; + + vdev = peer->vdev_priv->vdev; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("can't get tdls object"); + return; + } + + *reason = peer->reason; + + switch (peer->link_status) { + case TDLS_LINK_IDLE: + case TDLS_LINK_DISCOVERED: + case TDLS_LINK_DISCOVERING: + case TDLS_LINK_CONNECTING: + *state = QCA_WIFI_HAL_TDLS_S_ENABLED; + break; + case TDLS_LINK_CONNECTED: + if ((TDLS_IS_OFF_CHANNEL_ENABLED( + soc_obj->tdls_configs.tdls_feature_flags)) && + (soc_obj->tdls_fw_off_chan_mode == ENABLE_CHANSWITCH)) + *state = QCA_WIFI_HAL_TDLS_S_ESTABLISHED_OFF_CHANNEL; + else + *state = QCA_WIFI_HAL_TDLS_S_ENABLED; + break; + case TDLS_LINK_TEARING: + *state = QCA_WIFI_HAL_TDLS_S_DROPPED; + break; + } +} + +/** + * tdls_extract_peer_state_param() - extract peer update params from TDLS peer + * @peer_param: output peer update params + * @peer: TDLS peer + * + * This is used when enable TDLS link + * + * Return: None. + */ +void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, + struct tdls_peer *peer) +{ + uint16_t i, num; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + enum channel_state ch_state; + struct wlan_objmgr_pdev *pdev; + uint8_t chan_id; + + vdev_obj = peer->vdev_priv; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + pdev = wlan_vdev_get_pdev(vdev_obj->vdev); + if (!soc_obj || !pdev) { + tdls_err("soc_obj: %p, pdev: %p", soc_obj, pdev); + return; + } + + qdf_mem_zero(peer_param, sizeof(*peer_param)); + wlan_vdev_obj_lock(vdev_obj->vdev); + peer_param->vdev_id = wlan_vdev_get_id(vdev_obj->vdev); + wlan_vdev_obj_unlock(vdev_obj->vdev); + + qdf_mem_copy(peer_param->peer_macaddr, + peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); + peer_param->peer_state = TDLS_PEER_STATE_CONNCTED; + peer_param->peer_cap.is_peer_responder = peer->is_responder; + peer_param->peer_cap.peer_uapsd_queue = peer->uapsd_queues; + peer_param->peer_cap.peer_max_sp = peer->max_sp; + peer_param->peer_cap.peer_buff_sta_support = peer->buf_sta_capable; + peer_param->peer_cap.peer_off_chan_support = + peer->off_channel_capable; + peer_param->peer_cap.peer_curr_operclass = 0; + peer_param->peer_cap.self_curr_operclass = 0; + peer_param->peer_cap.peer_chanlen = peer->supported_channels_len; + peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num; + peer_param->peer_cap.pref_off_chan_bandwidth = + soc_obj->tdls_configs.tdls_pre_off_chan_bw; + peer_param->peer_cap.opclass_for_prefoffchan = + peer->op_class_for_pref_off_chan; + + if (wlan_reg_is_dfs_ch(pdev, peer_param->peer_cap.pref_off_channum)) { + tdls_err("Resetting TDLS off-channel from %d to %d", + peer_param->peer_cap.pref_off_channum, + WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); + peer_param->peer_cap.pref_off_channum = + WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF; + } + + num = 0; + for (i = 0; i < peer->supported_channels_len; i++) { + chan_id = peer->supported_channels[i]; + ch_state = wlan_reg_get_channel_state(pdev, chan_id); + + if (CHANNEL_STATE_INVALID != ch_state && + CHANNEL_STATE_DFS != ch_state && + !wlan_is_dsrc_channel(wlan_is_dsrc_channel(chan_id))) { + peer_param->peer_cap.peer_chan[num].chan_id = chan_id; + peer_param->peer_cap.peer_chan[num].pwr = + wlan_reg_get_channel_reg_power(pdev, chan_id); + peer_param->peer_cap.peer_chan[num].dfs_set = false; + num++; + } + } + + peer_param->peer_cap.peer_oper_classlen = + peer->supported_oper_classes_len; + for (i = 0; i < peer->supported_oper_classes_len; i++) + peer_param->peer_cap.peer_oper_class[i] = + peer->supported_oper_classes[i]; +} + +/** + * tdls_set_link_status() - set link statue for TDLS peer + * @vdev_obj: TDLS vdev object + * @mac: MAC address of current TDLS peer + * @link_status: link status + * @link_reason: reason with link status + * + * Return: None. + */ +void tdls_set_link_status(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *mac, + enum tdls_link_state link_status, + enum tdls_link_state_reason link_reason) +{ + uint32_t state = 0; + int32_t res = 0; + uint32_t op_class = 0; + uint32_t channel = 0; + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err("peer is NULL, can't set link status %d, reason %d", + link_status, link_reason); + return; + } + + peer->link_status = link_status; + + if (link_status >= TDLS_LINK_DISCOVERED) + peer->discovery_attempt = 0; + + if (peer->is_forced_peer && peer->state_change_notification) { + peer->reason = link_reason; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + tdls_determine_channel_opclass(soc_obj, vdev_obj, + peer, &channel, &op_class); + tdls_get_wifi_hal_state(peer, &state, &res); + peer->state_change_notification(mac, op_class, channel, + state, res, soc_obj->soc); + } +} + +void tdls_set_peer_link_status(struct tdls_peer *peer, + enum tdls_link_state link_status, + enum tdls_link_state_reason link_reason) +{ + uint32_t state = 0; + int32_t res = 0; + uint32_t op_class = 0; + uint32_t channel = 0; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + + peer->link_status = link_status; + + if (link_status >= TDLS_LINK_DISCOVERED) + peer->discovery_attempt = 0; + + if (peer->is_forced_peer && peer->state_change_notification) { + peer->reason = link_reason; + + vdev_obj = peer->vdev_priv; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + tdls_determine_channel_opclass(soc_obj, vdev_obj, + peer, &channel, &op_class); + tdls_get_wifi_hal_state(peer, &state, &res); + peer->state_change_notification(peer->peer_mac.bytes, + op_class, channel, state, + res, soc_obj->soc); + } +} + +void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, + struct tdls_update_peer_params *req_info) +{ + uint8_t is_buffer_sta, is_off_channel_supported, is_qos_wmm_sta; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer; + uint32_t feature; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return; + } + + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (!curr_peer) { + tdls_err("NULL tdls peer"); + return; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if ((1 << 4) & req_info->extn_capability[3]) + is_buffer_sta = 1; + + if ((1 << 6) & req_info->extn_capability[3]) + is_off_channel_supported = 1; + + if (TDLS_IS_WMM_ENABLED(feature) && req_info->is_qos_wmm_sta) + is_qos_wmm_sta = true; + + curr_peer->uapsd_queues = req_info->uapsd_queues; + curr_peer->max_sp = req_info->max_sp; + curr_peer->buf_sta_capable = is_buffer_sta; + curr_peer->off_channel_capable = is_off_channel_supported; + + qdf_mem_copy(curr_peer->supported_channels, + req_info->supported_channels, + req_info->supported_channels_len); + + curr_peer->supported_channels_len = req_info->supported_channels_len; + + qdf_mem_copy(curr_peer->supported_oper_classes, + req_info->supported_oper_classes, + req_info->supported_oper_classes_len); + + curr_peer->supported_oper_classes_len = + req_info->supported_oper_classes_len; + + curr_peer->qos = is_qos_wmm_sta; +} + +QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t sta_id) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + + peer->sta_id = sta_id; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t signature) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->signature = signature; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, bool forcepeer) +{ + struct tdls_peer *peer; + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->is_forced_peer = forcepeer; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_callback(struct tdls_peer *peer, + tdls_state_change_callback callback) +{ + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->state_change_notification = callback; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan, + uint32_t max_latency, uint32_t op_class, + uint32_t min_bandwidth) +{ + if (!peer) { + tdls_err("peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + peer->op_class_for_pref_off_chan = (uint8_t)op_class; + peer->pref_off_chan_num = (uint8_t)chan; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer; + struct tdls_user_config *config; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("NULL psoc object"); + return QDF_STATUS_E_FAILURE; + } + + curr_peer = tdls_find_peer(vdev_obj, macaddr); + if (!curr_peer) { + tdls_err("NULL tdls peer"); + return QDF_STATUS_E_FAILURE; + } + + if (!curr_peer->is_forced_peer) { + config = &soc_obj->tdls_configs; + curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num; + curr_peer->op_class_for_pref_off_chan = + tdls_find_opclass(soc_obj->soc, + curr_peer->pref_off_chan_num, + config->tdls_pre_off_chan_bw); + } + + tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + curr_peer->sta_id = 0; + + return QDF_STATUS_SUCCESS; +} + +void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + QDF_STATUS status; + + if (!vdev_obj) { + tdls_err("NULL tdls vdev object"); + return; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + if (peer && peer->is_peer_idle_timer_initialised) { + tdls_debug(QDF_MAC_ADDRESS_STR + ": destroy idle timer ", + QDF_MAC_ADDR_ARRAY( + peer->peer_mac.bytes)); + qdf_mc_timer_stop(&peer->peer_idle_timer); + qdf_mc_timer_destroy(&peer->peer_idle_timer); + } + status = qdf_list_peek_next(head, p_node, &p_node); + } + } +} + +void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj) +{ + uint16_t i; + struct tdls_peer *peer; + qdf_list_t *head; + qdf_list_node_t *p_node; + + if (!vdev_obj) { + tdls_err("NULL tdls vdev object"); + return; + } + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &vdev_obj->peer_list[i]; + + while (QDF_IS_STATUS_SUCCESS( + qdf_list_remove_front(head, &p_node))) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + qdf_mem_free(peer); + } + qdf_list_destroy(head); + } +} diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h new file mode 100644 index 0000000000..511b4d4ed0 --- /dev/null +++ b/core/src/wlan_tdls_peer.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2017 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: wlan_tdls_peer.h + * + * TDLS peer function declaration + */ + +#if !defined(_WLAN_TDLS_PEER_H_) +#define _WLAN_TDLS_PEER_H_ + +/** + * struct tdls_search_peer_param - used to search TDLS peer + * @macaddr: MAC address of peer + * @peer: pointer to the found peer + */ +struct tdls_search_peer_param { + const uint8_t *macaddr; + struct tdls_peer *peer; +}; + +/** + * struct tdls_progress_param - used to search progress TDLS peer + * @skip_self: skip self peer + * @macaddr: MAC address of peer + * @peer: pointer to the found peer + */ +struct tdls_search_progress_param { + uint8_t skip_self; + const uint8_t *macaddr; + struct tdls_peer *peer; +}; + +/** + * tdls_get_peer() - find or add an TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * Search the TDLS peer in the hash table and create a new one if not found. + * + * Return: Pointer to tdls_peer, NULL if failed. + */ +struct tdls_peer *tdls_get_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr); + +/** + * tdls_find_peer() - find TDLS peer in TDLS vdev object + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of peer + * + * This is in scheduler thread context, no lock required. + * + * Return: If peer is found, then it returns pointer to tdls_peer; + * otherwise, it returns NULL. + */ +struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr); + +/** + * tdls_find_all_peer() - find peer matching the input MACaddr in soc range + * @soc_obj: TDLS soc object + * @macaddr: MAC address of TDLS peer + * + * This is in scheduler thread context, no lock required. + * + * Return: TDLS peer if a matching is detected; NULL otherwise + */ +struct tdls_peer * +tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr); + +/** + * tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev + * @vdev_obj: tdls vdev object + * + * This function searches for the 1st connected TDLS peer + * + * Return: The 1st connected TDLS peer if found; NULL otherwise + */ +struct tdls_peer * +tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj); + +/** + * tdls_is_progress() - find the peer with ongoing TDLS progress on present psoc + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the peer + * @skip_self: if 1, skip checking self. If 0, search include self + * + * This is used in scheduler thread context, no lock required. + * + * Return: TDLS peer if found; NULL otherwise + */ +struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t skip_self); + +/** + * tdls_extract_peer_state_param() - extract peer update params from TDL peer + * @peer_param: output peer update params + * @peer: TDLS peer + * + * This is used when enable TDLS link + * + * Return: None. + */ +void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, + struct tdls_peer *peer); + +/** + * tdls_set_link_status() - set link statue for TDLS peer + * @peer: TDLS peer + * @link_state: link state + * @link_reason: reason with link status + * + * This is in scheduler thread context, no lock required. + * + * Return: None. + */ +void tdls_set_peer_link_status(struct tdls_peer *peer, + enum tdls_link_state link_state, + enum tdls_link_state_reason link_reason); + +/** + * tdls_set_peer_caps() - set capability for TDLS peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address for the TDLS peer + * @req_info: parameters to update peer capability + * + * This is in scheduler thread context, no lock required. + * + * Return: None. + */ +void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, + struct tdls_update_peer_params *req_info); + +/** + * tdls_set_sta_id() - set station ID on a TDLS peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the TDLS peer + * @sta_id: station ID + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t sta_id); + +/** + * tdls_set_signature() - set TDLS peer's signature + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of the TDLS peer + * @signature: signature value + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, uint8_t signature); + +/** + * tdls_set_force_peer() - set/clear is_forced_peer flag on peer + * @vdev_obj: TDLS vdev object + * @macaddr: MAC address of TDLS peer + * @forcepeer: value used to set is_forced_peer flag + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *macaddr, bool forcepeer); + +/** + * tdls_set_callback() - set state change callback on current TDLS peer + * @peer: TDLS peer + * @callback: state change callback + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_callback(struct tdls_peer *peer, + tdls_state_change_callback callback); + +/** + * tdls_set_extctrl_param() - set external control parameter on TDLS peer + * @peer: TDLS peer + * @chan: channel + * @max_latency: maximum latency + * @op_class: operation class + * @min_bandwidth: minimal bandwidth + * + * This is used in scheduler thread context, no lock required. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_set_extctrl_param(struct tdls_peer *peer, uint32_t chan, + uint32_t max_latency, uint32_t op_class, + uint32_t min_bandwidth); + +/** + * tdls_reset_peer() - reset TDLS peer identified by MAC address + * @vdev_obj: TDLS vdev object + * @mac: MAC address of the peer + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, + const uint8_t *mac); + +/** + * tdls_peer_idle_timers_destroy() - destroy peer idle timers + * @vdev_obj: TDLS vdev object + * + * Loop through the idle peer list and destroy their timers + * + * Return: None + */ +void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj); + +/** + * tdls_free_peer_list() - free TDLS peer list + * @vdev_obj: TDLS vdev object + * + * Free all the tdls peers + * + * Return: None + */ +void tdls_free_peer_list(struct tdls_vdev_priv_obj *vdev_obj); +#endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index d9b5d8da98..2f76979be4 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -30,15 +30,36 @@ #include #include -#define WLAN_TDLS_STA_MAX_NUM 8 -#define WLAN_TDLS_PEER_LIST_SIZE 256 -#define WLAN_TDLS_CT_TABLE_SIZE 8 -#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 -#define WLAN_MAC_MAX_EXTN_CAP 8 -#define WLAN_MAC_MAX_SUPP_CHANNELS 100 -#define WLAN_MAX_SUPP_OPER_CLASSES 32 -#define WLAN_MAC_MAX_SUPP_RATES 32 -#define ENABLE_CHANSWITCH 1 +#define WLAN_TDLS_STA_MAX_NUM 8 +#define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1 +#define WLAN_TDLS_PEER_LIST_SIZE 16 +#define WLAN_TDLS_CT_TABLE_SIZE 8 +#define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 +#define WLAN_MAC_MAX_EXTN_CAP 8 +#define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAX_SUPP_OPER_CLASSES 32 +#define WLAN_MAC_MAX_SUPP_RATES 32 +#define WLAN_CHANNEL_14 14 +#define ENABLE_CHANSWITCH 1 +#define DISABLE_CHANSWITCH 2 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 +#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36 + +/** Maximum time(ms) to wait for tdls add sta to complete **/ +#define WAIT_TIME_TDLS_ADD_STA 1500 + +/** Maximum time(ms) to wait for tdls del sta to complete **/ +#define WAIT_TIME_TDLS_DEL_STA 1500 + +/** Maximum time(ms) to wait for Link Establish Req to complete **/ +#define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 + +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_TDLS_MGMT 11000 + +#define TDLS_TEARDOWN_PEER_UNREACHABLE 25 +#define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 #define TDLS_STA_INDEX_CHECK(sta_id) \ (((sta_id) >= 1) && ((sta_id) < 0xFF)) @@ -65,7 +86,23 @@ enum tdls_peer_capab { }; /** - * enum tdls_link_status - tdls link status + * enum tdls_peer_state - tdls peer state + * @TDLS_PEER_STATE_PEERING: tdls connection in progress + * @TDLS_PEER_STATE_CONNCTED: tdls peer is connected + * @TDLS_PEER_STATE_TEARDOWN: tdls peer is tear down + * @TDLS_PEER_ADD_MAC_ADDR: add peer mac into connection table + * @TDLS_PEER_REMOVE_MAC_ADDR: remove peer mac from connection table + */ +enum tdls_peer_state { + TDLS_PEER_STATE_PEERING, + TDLS_PEER_STATE_CONNCTED, + TDLS_PEER_STATE_TEARDOWN, + TDLS_PEER_ADD_MAC_ADDR, + TDLS_PEER_REMOVE_MAC_ADDR +}; + +/** + * enum tdls_link_state - tdls link state * @TDLS_LINK_IDLE: tdls link idle * @TDLS_LINK_DISCOVERING: tdls link discovering * @TDLS_LINK_DISCOVERED: tdls link discovered @@ -73,7 +110,7 @@ enum tdls_peer_capab { * @TDLS_LINK_CONNECTED: tdls link connected * @TDLS_LINK_TEARING: tdls link tearing */ -enum tdls_link_status { +enum tdls_link_state { TDLS_LINK_IDLE = 0, TDLS_LINK_DISCOVERING, TDLS_LINK_DISCOVERED, @@ -83,7 +120,7 @@ enum tdls_link_status { }; /** - * enum tdls_link_reason - tdls link reason + * enum tdls_link_state_reason - tdls link reason * @TDLS_LINK_SUCCESS: Success * @TDLS_LINK_UNSPECIFIED: Unspecified reason * @TDLS_LINK_NOT_SUPPORTED: Remote side doesn't support TDLS @@ -91,7 +128,7 @@ enum tdls_link_status { * @TDLS_LINK_NOT_BENEFICIAL: Going to AP is better than direct * @TDLS_LINK_DROPPED_BY_REMOTE: Remote side doesn't want it anymore */ -enum tdls_link_reason { +enum tdls_link_state_reason { TDLS_LINK_SUCCESS, TDLS_LINK_UNSPECIFIED = -1, TDLS_LINK_NOT_SUPPORTED = -2, @@ -101,7 +138,7 @@ enum tdls_link_reason { }; /** - * enum tdls_support_mode - TDLS support mode + * enum tdls_feature_mode - TDLS support mode * @TDLS_SUPPORT_DISABLED: Disabled in ini or FW * @TDLS_SUPPORT_SUSPENDED: TDLS supported by ini and FW, but disabled * temporarily due to off-channel operations or due to other reasons @@ -109,7 +146,7 @@ enum tdls_link_reason { * @TDLS_SUPPORT_IMP_MODE: Implicit mode * @TDLS_SUPPORT_EXT_CONTROL: External control mode */ -enum tdls_support_mode { +enum tdls_feature_mode { TDLS_SUPPORT_DISABLED = 0, TDLS_SUPPORT_SUSPENDED, TDLS_SUPPORT_EXP_TRIG_ONLY, @@ -124,6 +161,9 @@ enum tdls_support_mode { * @TDLS_EVENT_RX_MGMT: rx discovery response frame * @TDLS_EVENT_ADD_PEER: add peer or update peer * @TDLS_EVENT_DEL_PEER: delete peer + * @TDLS_EVENT_DISCOVERY_REQ: dicovery request + * @TDLS_EVENT_TEARDOWN_REQ: teardown request + * @TDLS_EVENT_SETUP_REQ: setup request */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -131,11 +171,13 @@ enum tdls_event_type { TDLS_EVENT_RX_MGMT, TDLS_EVENT_ADD_PEER, TDLS_EVENT_DEL_PEER, + TDLS_EVENT_DISCOVERY_REQ, + TDLS_EVENT_TEARDOWN_REQ, + TDLS_EVENT_SETUP_REQ, }; /** * enum tdls_state_t - tdls state - * * @QCA_WIFI_HAL_TDLS_DISABLED: TDLS is not enabled, or is disabled now * @QCA_WIFI_HAL_TDLS_ENABLED: TDLS is enabled, but not yet tried * @QCA_WIFI_HAL_TDLS_ESTABLISHED: Direct link is established @@ -152,12 +194,25 @@ enum tdls_state_t { QCA_WIFI_HAL_TDLS_S_FAILED, }; +/** + * enum tdls_off_chan_mode - mode for WMI_TDLS_SET_OFFCHAN_MODE_CMDID + * @TDLS_ENABLE_OFFCHANNEL: enable off channel + * @TDLS_DISABLE_OFFCHANNEL: disable off channel + */ +enum tdls_off_chan_mode { + TDLS_ENABLE_OFFCHANNEL, + TDLS_DISABLE_OFFCHANNEL +}; + /** * enum tdls_event_msg_type - TDLS event message type - * @TDLS_SHOULD_DISCOVER: should do discover - * @TDLS_SHOULD_TEARDOWN: notify teardown the link + * @TDLS_SHOULD_DISCOVER: should do discover for peer (based on tx bytes per + * second > tx_discover threshold) + * @TDLS_SHOULD_TEARDOWN: recommend teardown the link for peer due to tx bytes + * per second below tx_teardown_threshold * @TDLS_PEER_DISCONNECTED: tdls peer disconnected - * @TDLS_CONNECTION_TRACKER_NOTIFY: connection tracker notify + * @TDLS_CONNECTION_TRACKER_NOTIFY: TDLS/BT role change notification for + * connection tracker */ enum tdls_event_msg_type { TDLS_SHOULD_DISCOVER = 0, @@ -168,19 +223,25 @@ enum tdls_event_msg_type { /** * enum tdls_event_reason - TDLS event reason - * @TDLS_TEARDOWN_TX: - * @TDLS_TEARDOWN_RSSI: - * @TDLS_TEARDOWN_SCAN: - * @TDLS_TEARDOWN_PTR_TIMEOUT: - * @TDLS_TEARDOWN_BAD_PTR: - * @TDLS_TEARDOWN_NO_RSP: - * @TDLS_DISCONNECTED_PEER_DELETE: - * @TDLS_PEER_ENTER_BUF_STA: - * @TDLS_PEER_EXIT_BUF_STA: - * @TDLS_ENTER_BT_BUSY: - * @TDLS_EXIT_BT_BUSY: - * @DLS_SCAN_STARTED: - * @TDLS_SCAN_COMPLETED: + * @TDLS_TEARDOWN_TX: tdls teardown recommended due to low transmits + * @TDLS_TEARDOWN_RSSI: tdls link tear down recommended due to poor RSSI + * @TDLS_TEARDOWN_SCAN: tdls link tear down recommended due to offchannel scan + * @TDLS_TEARDOWN_PTR_TIMEOUT: tdls peer disconnected due to PTR timeout + * @TDLS_TEARDOWN_BAD_PTR: tdls peer disconnected due wrong PTR format + * @TDLS_TEARDOWN_NO_RSP: tdls peer not responding + * @TDLS_DISCONNECTED_PEER_DELETE: tdls peer disconnected due to peer deletion + * @TDLS_PEER_ENTER_BUF_STA: tdls entered buffer STA role, TDLS connection + * tracker needs to handle this + * @TDLS_PEER_EXIT_BUF_STA: tdls exited buffer STA role, TDLS connection tracker + * needs to handle this + * @TDLS_ENTER_BT_BUSY: BT entered busy mode, TDLS connection tracker needs to + * handle this + * @TDLS_EXIT_BT_BUSY: BT exited busy mode, TDLS connection tracker needs to + * handle this + * @DLS_SCAN_STARTED: TDLS module received a scan start event, TDLS connection + * tracker needs to handle this + * @TDLS_SCAN_COMPLETED: TDLS module received a scan complete event, TDLS + * connection tracker needs to handle this */ enum tdls_event_reason { TDLS_TEARDOWN_TX, @@ -198,6 +259,19 @@ enum tdls_event_reason { TDLS_SCAN_COMPLETED, }; +/** + * struct tdls_osif_indication - tdls indication to os if layer + * @vdev: vdev object + * @reason: used with teardown indication + * @peer_mac: MAC address of the TDLS peer + */ +struct tdls_osif_indication { + struct wlan_objmgr_vdev *vdev; + uint16_t reason; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + QDF_STATUS status; +}; + /** * struct tx_frame - tx frame * @buf: frame buffer @@ -268,13 +342,14 @@ enum tdls_feature_bit { * @tdls_pre_off_chan_num: tdls off channel number * @tdls_pre_off_chan_bw: tdls off channel bandwidth * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer + * @delayed_trig_framint: delayed trigger frame interval */ struct tdls_user_config { uint32_t tdls_tx_states_period; uint32_t tdls_tx_pkt_threshold; uint32_t tdls_rx_pkt_threshold; uint32_t tdls_max_discovery_attempt; - uint32_t tdls_idle_timeoute; + uint32_t tdls_idle_timeout; uint32_t tdls_idle_pkt_threshold; uint32_t tdls_rssi_trigger_threshold; uint32_t tdls_rssi_teardown_threshold; @@ -287,6 +362,7 @@ struct tdls_user_config { uint32_t tdls_pre_off_chan_num; uint32_t tdls_pre_off_chan_bw; uint32_t tdls_peer_kickout_threshold; + uint32_t delayed_trig_framint; }; /** @@ -331,32 +407,60 @@ struct tdls_tx_cnf { /* This callback is used to report state change of peer to wpa_supplicant */ typedef int (*tdls_state_change_callback)(const uint8_t *mac, - uint32_t opclass, - uint32_t channel, - uint32_t state, - int32_t reason, void *ctx); + uint32_t opclass, + uint32_t channel, + uint32_t state, + int32_t reason, void *ctx); /* This callback is used to report events to os_if layer */ -typedef QDF_STATUS (*tdls_evt_callback) (void *data, - enum tdls_event_type ev_type, - void *event); +typedef void (*tdls_evt_callback) (void *data, + enum tdls_event_type ev_type, + struct tdls_osif_indication *event); /* prototype of callback registered by hdd to receive the ack cnf */ typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, - struct tdls_tx_cnf *tx_ack_cnf_cb_data); + struct tdls_tx_cnf *tx_ack_cnf_cb_data); +/* This callback is used to register TDLS peer with TL */ +typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, + uint32_t vdev_id, + const uint8_t *mac, + uint16_t stat_id, + uint8_t ucastsig, + uint8_t qos); + +/* This callback is used to deregister TDLS peer */ +typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, + uint32_t vdev_id, + uint8_t sta_id); /** * struct tdls_start_params - tdls start params + * @config: tdls user config + * @tdls_send_mgmt_req: pass eWNI_SME_TDLS_SEND_MGMT_REQ value + * @tdls_add_sta_req: pass eWNI_SME_TDLS_ADD_STA_REQ value + * @tdls_del_sta_req: pass eWNI_SME_TDLS_DEL_STA_REQ value + * @tdls_update_peer_state: pass WMA_UPDATE_TDLS_PEER_STATE value * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data + * @tdls_reg_tl_peer: tdls register tdls peer + * @tdls_dereg_tl_peer: tdls deregister tdls peer + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { + struct tdls_user_config config; + uint16_t tdls_send_mgmt_req; + uint16_t tdls_add_sta_req; + uint16_t tdls_del_sta_req; + uint16_t tdls_update_peer_state; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; + tdls_register_tl_peer_callback tdls_reg_tl_peer; + tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + void *tdls_tl_peer_data; }; /** @@ -366,7 +470,7 @@ struct tdls_start_params { * @vdev_id: vdev id */ struct tdls_add_peer_params { - const uint8_t *peer_addr; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; uint32_t peer_type; uint32_t vdev_id; }; @@ -437,7 +541,7 @@ struct vhtcap { }; struct tdls_update_peer_params { - const uint8_t *peer_addr; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; uint32_t peer_type; uint32_t vdev_id; uint16_t capability; @@ -454,6 +558,7 @@ struct tdls_update_peer_params { uint8_t supported_channels[WLAN_MAC_MAX_SUPP_CHANNELS]; uint8_t supported_oper_classes_len; uint8_t supported_oper_classes[WLAN_MAX_SUPP_OPER_CLASSES]; + bool is_qos_wmm_sta; }; struct tdls_update_peer_request { @@ -461,6 +566,36 @@ struct tdls_update_peer_request { struct tdls_update_peer_params update_peer_req; }; +/** + * struct tdls_oper_request - tdls operation request + * @vdev: vdev object + * @peer_addr: MAC address of the TDLS peer + */ +struct tdls_oper_request { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; +}; + +/** + * struct tdls_oper_config_force_peer_request - tdls enable force peer request + * @vdev: vdev object + * @peer_addr: MAC address of the TDLS peer + * @chan: channel + * @max_latency: maximum latency + * @op_class: operation class + * @min_bandwidth: minimal bandwidth + * @callback: state change callback + */ +struct tdls_oper_config_force_peer_request { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; + uint32_t chan; + uint32_t max_latency; + uint32_t op_class; + uint32_t min_bandwidth; + tdls_state_change_callback callback; +}; + /** * struct tdls_info - tdls info * @@ -550,20 +685,22 @@ struct tdls_peer_params { }; /** - * struct tdls_peer_update_params - TDLS peer state parameters + * struct tdls_peer_update_state - TDLS peer state parameters * @vdev_id: vdev id * @peer_macaddr: peer mac address * @peer_cap: peer capabality + * @resp_reqd: response needed */ -struct tdls_peer_update_params { +struct tdls_peer_update_state { uint32_t vdev_id; uint8_t peer_macaddr[QDF_MAC_ADDR_SIZE]; uint32_t peer_state; struct tdls_peer_params peer_cap; + bool resp_reqd; }; /** - * struct tdls_chan_switch_params - channel switch parameter structure + * struct tdls_channel_switch_params - channel switch parameter structure * @vdev_id: vdev ID * @peer_mac_addr: Peer mac address * @tdls_off_ch_bw_offset: Target off-channel bandwitdh offset @@ -571,7 +708,7 @@ struct tdls_peer_update_params { * @oper_class: Operating class for target channel * @is_responder: Responder or initiator */ -struct tdls_chan_switch_params { +struct tdls_channel_switch_params { uint32_t vdev_id; uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE]; uint16_t tdls_off_ch_bw_offset; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 02d8c2beff..052f55b094 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -28,6 +28,9 @@ #include #include #include +#include +#include +#include /** * ucfg_tdls_init() - TDLS module initialization API @@ -66,8 +69,9 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc); * * Return: QDF_STATUS */ -QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, - struct tdls_start_params *req); +QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req); + /** * ucfg_tdls_psoc_stop() - TDLS module stop * @psoc: psoc object @@ -75,4 +79,24 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, * Return: QDF_STATUS */ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_add_peer() - handle TDLS add peer + * @vdev: vdev object + * @add_peer_req: add peer request parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_add_peer_params *add_peer_req); + +/** + * ucfg_tdls_update_peer() - handle TDLS update peer + * @vdev: vdev object + * @update_peer: update TDLS request parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_update_peer_params *update_peer); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 3d49c5adac..045d99d1e9 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -24,6 +24,7 @@ #include #include "../../core/src/wlan_tdls_main.h" +#include "../../core/src/wlan_tdls_cmds_process.h" #include #include @@ -113,6 +114,7 @@ QDF_STATUS ucfg_tdls_deinit(void) static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) { uint8_t sta_idx; + uint32_t feature; soc_obj->connected_peer_count = 0; soc_obj->tdls_nss_switch_in_progress = false; @@ -120,7 +122,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->tdls_nss_teardown_complete = false; soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; - soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (TDLS_IS_BUFFER_STA_ENABLED(feature) || + TDLS_IS_SLEEP_STA_ENABLED(feature) || + TDLS_IS_OFF_CHANNEL_ENABLED(feature)) + soc_obj->max_num_tdls_sta = + WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM; + else + soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; + for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { soc_obj->tdls_conn_info[sta_idx].sta_id = 0; @@ -142,7 +153,7 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) tdls_notice("tdls psoc open"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -152,15 +163,21 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) return status; } -QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, - struct tdls_start_params *req) +QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, + struct tdls_start_params *req) { struct tdls_soc_priv_obj *soc_obj; + uint32_t tdls_feature_flags; + + tdls_notice("tdls update config "); + if (!psoc || !req) { + tdls_err("psoc: 0x%p, req: 0x%p", psoc, req); + return QDF_STATUS_E_FAILURE; + } - tdls_notice("tdls psoc start"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -171,6 +188,28 @@ QDF_STATUS ucfg_tdls_psoc_start(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; + /* Save callbacks to register/deregister TDLS sta with TL */ + soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; + soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; + soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; + + /* Save legacy PE/WMA commands in TDLS soc object */ + soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; + soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; + soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; + soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + + /* Update TDLS user config */ + qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); + tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; + + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + soc_obj->tdls_current_mode = TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) + soc_obj->tdls_current_mode = TDLS_SUPPORT_EXT_CONTROL; + else + soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE; + return QDF_STATUS_SUCCESS; } @@ -181,7 +220,7 @@ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) tdls_notice("tdls psoc stop"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - if (soc_obj == NULL) { + if (!soc_obj) { tdls_err("Failed to get tdls psoc component"); return QDF_STATUS_E_FAILURE; } @@ -203,3 +242,93 @@ QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) return status; } + +QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_add_peer_params *add_peer_req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_add_peer_request *req; + QDF_STATUS status; + + if (!vdev || !add_peer_req) { + tdls_err("vdev: %p, req %p", vdev, add_peer_req); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("vdevid: %d, peertype: %d", + add_peer_req->vdev_id, add_peer_req->peer_type); + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + return status; + } + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + status = QDF_STATUS_E_NOMEM; + goto dec_ref; + } + + qdf_mem_copy(&req->add_peer_req, add_peer_req, sizeof(*add_peer_req)); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_ADD_STA; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post add peer msg fail"); + qdf_mem_free(req); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + return status; +} + +QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, + struct tdls_update_peer_params *update_peer) +{ + struct scheduler_msg msg = {0,}; + struct tdls_update_peer_request *req; + QDF_STATUS status; + + if (!vdev || !update_peer) { + tdls_err("vdev: %p, update_peer: %p", vdev, update_peer); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_debug("vdev_id: %d, peertype: %d", + update_peer->vdev_id, update_peer->peer_type); + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + return status; + } + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + status = QDF_STATUS_E_NOMEM; + goto dec_ref; + } + qdf_mem_copy(&req->update_peer_req, update_peer, sizeof(*update_peer)); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_CHANGE_STA; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post update peer msg fail"); + qdf_mem_free(req); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + return status; +} From 96bbde31a638cb9128ac5773711c6f5d8319f78f Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 11 Apr 2017 22:37:03 +0800 Subject: [PATCH 03/89] qcacmn: TDLS component: south interface Add lmac_if layer changes for TDLS Change-Id: Ic842857ce7ebc83d2a22a8a8e23c60df1c3dbfc8 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 2 +- dispatcher/inc/wlan_tdls_public_structs.h | 56 ++++++++ dispatcher/inc/wlan_tdls_tgt_api.h | 91 ++++++++++++ dispatcher/src/wlan_tdls_tgt_api.c | 162 ++++++++++++++++++++++ 4 files changed, 310 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 12dde2563d..4e1f0f0db1 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -981,7 +981,7 @@ error: } /** - * tdls_process_add_peer_rsp() - handle response for add TDLS peer + * tdls_add_peer_rsp() - handle response for add TDLS peer * @rsp: TDLS add peer response * * Return: QDF_STATUS_SUCCESS for success; other values if failed diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 2f76979be4..4fc129ebea 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -718,6 +718,62 @@ struct tdls_channel_switch_params { uint8_t is_responder; }; +/** + * enum uapsd_access_cat - U-APSD Access Categories + * @UAPSD_AC_BE: best effort + * @UAPSD_AC_BK: back ground + * @UAPSD_AC_VI: video + * @UAPSD_AC_VO: voice + */ +enum uapsd_access_cat { + UAPSD_AC_BE, + UAPSD_AC_BK, + UAPSD_AC_VI, + UAPSD_AC_VO +}; + +/** + * enum tspec_dir_type - TSPEC Direction type + * @TX_DIR: uplink + * @RX_DIR: downlink + * @BI_DIR: bidirectional + */ +enum tspec_dir_type { + TX_DIR = 0, + RX_DIR = 1, + BI_DIR = 2, +}; + +/** + * struct sta_uapsd_params - uapsd auto trig params + * @wmm_ac: WMM access category from 0 to 3 + * @user_priority: User priority to use in trigger frames + * @service_interval: service interval + * @suspend_interval: suspend interval + * @delay_interval: delay interval + */ +struct sta_uapsd_params { + uint32_t wmm_ac; + uint32_t user_priority; + uint32_t service_interval; + uint32_t suspend_interval; + uint32_t delay_interval; +}; + +/** + * struct sta_uapsd_trig_params - uapsd trigger parameter + * @vdevid: vdev id + * @peer_addr: peer address + * @auto_triggerparam: trigger parameters + * @num_ac: no of access category + */ +struct sta_uapsd_trig_params { + uint32_t vdevid; + uint8_t peer_addr[QDF_MAC_ADDR_SIZE]; + struct sta_uapsd_params *auto_triggerparam; + uint32_t num_ac; +}; + /** * struct tdls_event_info - firmware tdls event * @vdev_id: vdev id diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 78454e0829..dbc8c0683f 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -21,3 +21,94 @@ * * TDLS south bound interface declaration */ + +#ifndef _WLAN_TDLS_TGT_API_H_ +#define _WLAN_TDLS_TGT_API_H_ +#include +#include "../../core/src/wlan_tdls_main.h" + +/** + * tgt_tdls_set_fw_state() - invoke lmac tdls update fw + * @psoc: soc object + * @tdls_param: update tdls state parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *tdls_param); + +/** + * tgt_tdls_set_peer_state() - invoke lmac tdls update peer state + * @psoc: soc object + * @peer_param: update tdls peer parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_param); + +/** + * tgt_tdls_set_offchan_mode() - invoke lmac tdls set off-channel mode + * @psoc: soc object + * @param: set tdls off channel parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param); + +/** + * tgt_tdls_set_uapsd()- invoke lamc tdls set uapsd function + * @psoc: soc object + * @params: uapsd parameters + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params); + +/** + * tgt_tdls_del_peer_rsp() - handle TDLS del peer response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_add_peer_rsp() - handle TDLS add peer response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_register_ev_handler() - invoke lmac register tdls event handler + * @psoc: soc object + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ +QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_tdls_unregister_ev_handler() - invoke lmac unregister tdls event handler + * @psoc: soc object + * + * Return: QDF_STATUS_SUCCESS for success or error code. + */ +QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc); + +/** + * tgt_tdls_event_handler() - The callback registered to WMI for tdls events + * @psoc: psoc object + * @info: tdls event info + * + * The callback is registered by tgt as tdls rx ops handler. + * + * Return: 0 for success or err code. + */ +QDF_STATUS +tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, + struct tdls_event_info *info); +#endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 864886bb4b..78a198b2a7 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -21,3 +21,165 @@ * * TDLS south bound interface definitions */ + +#include "qdf_status.h" +#include +#include "../../core/src/wlan_tdls_main.h" +#include "../../core/src/wlan_tdls_cmds_process.h" + +static inline struct wlan_lmac_if_tdls_tx_ops * +wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.tx_ops.tdls_tx_ops; +} + +static inline struct wlan_lmac_if_tdls_rx_ops * +wlan_psoc_get_tdls_rxops(struct wlan_objmgr_psoc *psoc) +{ + return &psoc->soc_cb.rx_ops.tdls_rx_ops; +} + +QDF_STATUS tgt_tdls_set_fw_state(struct wlan_objmgr_psoc *psoc, + struct tdls_info *tdls_param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->update_fw_state) + return tdls_ops->update_fw_state(psoc, tdls_param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_peer_state(struct wlan_objmgr_psoc *psoc, + struct tdls_peer_update_state *peer_param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->update_peer_state) + return tdls_ops->update_peer_state(psoc, peer_param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->set_offchan_mode) + return tdls_ops->set_offchan_mode(psoc, param); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, + struct sta_uapsd_trig_params *params) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->tdls_set_uapsd) + return tdls_ops->tdls_set_uapsd(psoc, params); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_add_peer_rsp(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_del_peer_rsp(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_register_ev_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops && tdls_ops->tdls_reg_ev_handler) + return tdls_ops->tdls_reg_ev_handler(psoc, NULL); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_lmac_if_tdls_tx_ops *tdls_ops = NULL; + + tdls_ops = wlan_psoc_get_tdls_txops(psoc); + if (tdls_ops->tdls_unreg_ev_handler) + return tdls_ops->tdls_unreg_ev_handler(psoc, NULL); + else + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, + struct tdls_event_info *info) +{ + struct scheduler_msg msg = {0,}; + struct tdls_event_notify *notify; + uint8_t vdev_id; + QDF_STATUS status; + + if (!psoc || !info) { + tdls_err("psoc: 0x%p, info: 0x%p", psoc, info); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, + info->vdev_id, info->message_type, info->peer_reason, + QDF_MAC_ADDR_ARRAY(info->peermac.bytes)); + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + vdev_id = info->vdev_id; + notify->vdev = + wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, WLAN_TDLS_SB_ID); + if (!notify->vdev) { + tdls_err("null vdev, vdev_id: %d, psoc: 0x%p", vdev_id, psoc); + return QDF_STATUS_E_INVAL; + } + qdf_mem_copy(¬ify->event, info, sizeof(*info)); + + msg.bodyptr = notify; + msg.callback = tdls_process_evt; + + status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't post msg to handle tdls event"); + wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + } + + return status; +} From 8cbcde2860a9efc3e7b39321c054c7db857d2f4f Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Mon, 20 Mar 2017 14:39:07 +0800 Subject: [PATCH 04/89] qcacmn: TDLS component: core tdls_oper operations Implement TDLS oper fucntions Change-Id: Ibdd1fa30ef5b72fbbe8316f88d8c4b9deab1a5a7 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 442 ++++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 26 ++ core/src/wlan_tdls_main.c | 6 +- core/src/wlan_tdls_main.h | 24 -- dispatcher/inc/wlan_tdls_public_structs.h | 29 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 11 + dispatcher/src/wlan_tdls_ucfg_api.c | 64 ++++ 7 files changed, 576 insertions(+), 26 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 4e1f0f0db1..1c5d68454b 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -21,10 +21,12 @@ * * TDLS north bound commands implementation */ +#include #include #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_tgt_api.h" static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) { @@ -35,6 +37,8 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) * tdls_decrement_peer_count() - decrement connected TDLS peer counter * @soc_obj: TDLS soc object * + * Used in scheduler thread context, no lock needed. + * * Return: None. */ static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) @@ -45,6 +49,20 @@ static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); } +/** + * tdls_increment_peer_count() - increment connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Used in scheduler thread context, no lock needed. + * + * Return: None. + */ +static void tdls_increment_peer_count(struct tdls_soc_priv_obj *soc_obj) +{ + soc_obj->connected_peer_count++; + tdls_debug("Connected peer count %d", soc_obj->connected_peer_count); +} + /** * tdls_validate_current_mode() - check current TDL mode * @soc_obj: TDLS soc object @@ -1169,3 +1187,427 @@ error: return status; } + +static QDF_STATUS +tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, + struct tdls_peer_update_state *peer_state) +{ + struct scheduler_msg msg = {0,}; + QDF_STATUS status; + + tdls_debug("update TDLS peer " QDF_MAC_ADDRESS_STR " vdev %d, state %d", + QDF_MAC_ADDR_ARRAY(peer_state->peer_macaddr), + peer_state->vdev_id, peer_state->peer_state); + msg.type = soc_obj->tdls_update_peer_state; + msg.reserved = 0; + msg.bodyptr = peer_state; + + status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("scheduler_post_msg failed"); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} + +static QDF_STATUS +tdls_update_uapsd(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, + uint8_t sta_id, uint32_t srvc_int, uint32_t sus_int, + uint8_t dir, uint8_t psb, uint32_t delay_interval) +{ + uint8_t i; + static const uint8_t ac[AC_PRIORITY_NUM] = {UAPSD_AC_VO, UAPSD_AC_VI, + UAPSD_AC_BK, UAPSD_AC_BE}; + static const uint8_t tid[AC_PRIORITY_NUM] = {7, 5, 2, 3}; + uint32_t vdev_id; + + struct sta_uapsd_params tdls_uapsd_params; + struct sta_uapsd_trig_params tdls_trig_params; + struct wlan_objmgr_peer *bsspeer; + uint8_t macaddr[QDF_MAC_ADDR_SIZE]; + QDF_STATUS status; + + if (!psb) { + tdls_debug("No need to configure auto trigger:psb is 0"); + return QDF_STATUS_SUCCESS; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + bsspeer = wlan_vdev_get_bsspeer(vdev); + if (!bsspeer) { + wlan_vdev_obj_unlock(vdev); + tdls_err("bss peer is NULL"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(macaddr, + wlan_peer_get_macaddr(bsspeer), QDF_MAC_ADDR_SIZE); + wlan_vdev_obj_unlock(vdev); + + tdls_debug("TDLS uapsd id %d, srvc %d, sus %d, dir %d psb %d delay %d", + sta_id, srvc_int, sus_int, dir, psb, delay_interval); + for (i = 0; i < AC_PRIORITY_NUM; i++) { + tdls_uapsd_params.wmm_ac = ac[i]; + tdls_uapsd_params.user_priority = tid[i]; + tdls_uapsd_params.service_interval = srvc_int; + tdls_uapsd_params.delay_interval = delay_interval; + tdls_uapsd_params.suspend_interval = sus_int; + + tdls_trig_params.vdevid = vdev_id; + tdls_trig_params.num_ac = 1; + tdls_trig_params.auto_triggerparam = &tdls_uapsd_params; + + qdf_mem_copy(tdls_trig_params.peer_addr, + macaddr, QDF_MAC_ADDR_SIZE); + status = tgt_tdls_set_uapsd(psoc, &tdls_trig_params); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Failed to set uapsd for vdev %d, status %d", + vdev_id, status); + } + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) +{ + struct tdls_peer *peer; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + uint8_t *mac; + struct tdls_peer_update_state *peer_update_param; + QDF_STATUS status; + uint32_t feature; + uint8_t id; + + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(req); + return QDF_STATUS_E_NULL_VALUE; + } + + /* vdev reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + + if (!vdev_obj || !soc_obj) { + tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + mac = req->peer_addr; + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err(QDF_MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_ENABLE_LINK", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + tdls_debug("enable link for peer " QDF_MAC_ADDRESS_STR " link state %d", + QDF_MAC_ADDR_ARRAY(mac), peer->link_status); + if (!TDLS_STA_INDEX_CHECK(peer->sta_id)) { + tdls_err("invalid sta idx %u for " QDF_MAC_ADDRESS_STR, + peer->sta_id, QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + peer->tdls_support = TDLS_CAP_SUPPORTED; + if (TDLS_LINK_CONNECTED != peer->link_status) + tdls_set_peer_link_status(peer, TDLS_LINK_CONNECTED, + TDLS_LINK_SUCCESS); + + wlan_vdev_obj_lock(vdev); + id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, + id, mac, peer->sta_id, + peer->signature, peer->qos); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("TDLS register with TL fail, status %d", status); + goto error; + } + + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + status = QDF_STATUS_E_NOMEM; + goto error; + } + + tdls_extract_peer_state_param(peer_update_param, peer); + + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(peer_update_param); + status = QDF_STATUS_E_PERM; + goto error; + } + + tdls_increment_peer_count(soc_obj); + feature = soc_obj->tdls_configs.tdls_feature_flags; + + tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", + TDLS_IS_BUFFER_STA_ENABLED(feature), + soc_obj->tdls_configs.tdls_uapsd_mask); + + if (TDLS_IS_BUFFER_STA_ENABLED(feature) || + soc_obj->tdls_configs.tdls_uapsd_mask) + tdls_update_uapsd(soc_obj->soc, + vdev, peer->sta_id, 0, 0, BI_DIR, 1, + soc_obj->tdls_configs.delayed_trig_framint); +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return status; +} + +/** + * tdls_config_force_peer() - configure an externally controllable TDLS peer + * @req: TDLS operation request + * + * This is not the tdls_process_cmd function. No need to acquire the reference + * count, release reference count and free the request, the caller handle it + * correctly. + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +static QDF_STATUS tdls_config_force_peer( + struct tdls_oper_config_force_peer_request *req) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_pdev *pdev; + struct wlan_objmgr_vdev *vdev; + const uint8_t *macaddr; + uint32_t feature; + QDF_STATUS status; + struct tdls_peer_update_state *peer_update_param; + + macaddr = req->peer_addr; + tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + + vdev = req->vdev; + wlan_vdev_obj_lock(vdev); + pdev = wlan_vdev_get_pdev(vdev); + wlan_vdev_obj_unlock(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!pdev || !vdev_obj || !soc_obj) { + tdls_err("pdev: %p, vdev_obj: %p, soc_obj: %p", + pdev, vdev_obj, soc_obj); + return QDF_STATUS_E_INVAL; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { + tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); + return QDF_STATUS_E_NOSUPPORT; + } + + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + return QDF_STATUS_E_NOMEM; + } + + peer = tdls_get_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer " QDF_MAC_ADDRESS_STR " does not exist", + QDF_MAC_ADDR_ARRAY(macaddr)); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + status = tdls_set_force_peer(vdev_obj, macaddr, true); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set force peer failed"); + goto error; + } + + /* Update the peer mac to firmware, so firmware could update the + * connection table + */ + wlan_vdev_obj_lock(vdev); + peer_update_param->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + qdf_mem_copy(peer_update_param->peer_macaddr, + macaddr, QDF_MAC_ADDR_SIZE); + peer_update_param->peer_state = TDLS_PEER_ADD_MAC_ADDR; + + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("update peer state failed"); + goto error; + } + + soc_obj->tdls_external_peer_count++; + + /* Validate if off channel is DFS channel */ + if (wlan_reg_is_dfs_ch(pdev, req->chan)) { + tdls_err("Resetting TDLS off-channel from %d to %d", + req->chan, WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF); + req->chan = WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF; + } + tdls_set_extctrl_param(peer, req->chan, req->max_latency, req->op_class, + req->min_bandwidth); + + tdls_set_callback(peer, req->callback); + + return status; +error: + qdf_mem_free(peer_update_param); + return status; +} + +/** + * tdls_process_setup_peer() - process configure an externally + * controllable TDLS peer + * @req: TDLS operation request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) +{ + struct tdls_oper_config_force_peer_request peer_req; + struct tdls_soc_priv_obj *soc_obj; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status; + + tdls_debug("Configure external TDLS peer " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(req->peer_addr)); + + /* reference cnt is acquired in ucfg_tdls_oper */ + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + status = QDF_STATUS_E_NULL_VALUE; + goto freereq; + } + + qdf_mem_zero(&peer_req, sizeof(peer_req)); + peer_req.vdev = vdev; + qdf_mem_copy(peer_req.peer_addr, req->peer_addr, QDF_MAC_ADDR_SIZE); + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!soc_obj) { + tdls_err("NULL soc object"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + peer_req.chan = soc_obj->tdls_configs.tdls_pre_off_chan_num; + + status = tdls_config_force_peer(&peer_req); +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +freereq: + qdf_mem_free(req); + + return status; +} + +QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) +{ + struct tdls_peer *peer; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev; + const uint8_t *macaddr; + uint32_t feature; + QDF_STATUS status; + struct tdls_peer_update_state *peer_update_param; + struct tdls_osif_indication ind; + + macaddr = req->peer_addr; + tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_ARRAY(macaddr)); + + vdev = req->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(req); + return QDF_STATUS_E_NULL_VALUE; + } + + /* reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + status = QDF_STATUS_E_INVAL; + goto error; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) || + !TDLS_IS_IMPLICIT_TRIG_ENABLED(feature)) { + tdls_err("TDLS ext ctrl or Imp Trig not enabled, %x", feature); + status = QDF_STATUS_E_NOSUPPORT; + goto error; + } + + peer = tdls_find_peer(vdev_obj, macaddr); + if (!peer) { + tdls_err("peer matching " QDF_MAC_ADDRESS_STR " not found", + QDF_MAC_ADDR_ARRAY(macaddr)); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + tdls_set_peer_link_status(peer, TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + + if (soc_obj->tdls_event_cb) { + qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); + ind.vdev = vdev; + ind.reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &ind); + } + + status = tdls_set_force_peer(vdev_obj, macaddr, false); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("set force peer failed"); + status = QDF_STATUS_E_INVAL; + goto error; + } + + if (soc_obj->tdls_external_peer_count) + soc_obj->tdls_external_peer_count--; + + tdls_set_callback(peer, NULL); + peer_update_param = qdf_mem_malloc(sizeof(*peer_update_param)); + if (!peer_update_param) { + tdls_err("memory allocation failed"); + status = QDF_STATUS_E_NOMEM; + goto error; + } + + wlan_vdev_obj_lock(vdev); + peer_update_param->vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + qdf_mem_copy(peer_update_param->peer_macaddr, + macaddr, QDF_MAC_ADDR_SIZE); + peer_update_param->peer_state = TDLS_PEER_REMOVE_MAC_ADDR; + status = tdls_wma_update_peer_state(soc_obj, peer_update_param); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(peer_update_param); + goto error; + } + + /*TODO set tdls connection tracker state*/ +error: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 253403f550..ff643199b1 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -163,6 +163,32 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req); */ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req); +/** + * tdls_process_enable_link() - enable TDLS link + * @req: TDLS enable link request + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed + */ +QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req); + +/** + * tdls_process_setup_peer() - process configure an externally + * controllable TDLS peer + * @req: TDLS configure force peer request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req); + +/** + * tdls_process_remove_force_peer() - process remove an externally controllable + * TDLS peer + * @req: TDLS operation request + * + * Return: QDF_STATUS_SUCCESS if success; other values if failed + */ +QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req); + /** * tdls_process_update_peer() - update TDLS peer * @req: TDLS update peer request diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index ab4a5e5c9a..4023edd5e4 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -202,10 +202,11 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%p, bodyptr: 0x%p", msg, msg->bodyptr); + tdls_err("msg: 0x%p", msg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } + tdls_debug("TDLS process command: %d", msg->type); switch (msg->type) { case TDLS_CMD_TX_ACTION: @@ -217,13 +218,16 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) tdls_process_update_peer(msg->bodyptr); break; case TDLS_CMD_ENABLE_LINK: + tdls_process_enable_link(msg->bodyptr); break; case TDLS_CMD_DISABLE_LINK: tdls_process_del_peer(msg->bodyptr); break; case TDLS_CMD_CONFIG_FORCE_PEER: + tdls_process_setup_peer(msg->bodyptr); break; case TDLS_CMD_REMOVE_FORCE_PEER: + tdls_process_remove_force_peer(msg->bodyptr); break; case TDLS_CMD_STATS_UPDATE: break; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 4d4d5f2bbd..0432502034 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -97,30 +97,6 @@ enum tdls_nss_transition_state { TDLS_NSS_TRANSITION_S_1x1_to_2x2, }; -/** - * enum tdls_command_type - TDLS command type - * @TDLS_CMD_TX_ACTION: send tdls action frame - * @TDLS_CMD_ADD_STA: add tdls peer - * @TDLS_CMD_CHANGE_STA: change tdls peer - * @TDLS_CMD_ENABLE_LINK: enable tdls link - * @TDLS_CMD_DISABLE_LINK: disable tdls link - * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer - * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer - * @TDLS_CMD_STATS_UPDATE: update tdls stats - * @TDLS_CMD_CONFIG_UPDATE: config tdls - */ -enum tdls_commmand_type { - TDLS_CMD_TX_ACTION = 1, - TDLS_CMD_ADD_STA, - TDLS_CMD_CHANGE_STA, - TDLS_CMD_ENABLE_LINK, - TDLS_CMD_DISABLE_LINK, - TDLS_CMD_CONFIG_FORCE_PEER, - TDLS_CMD_REMOVE_FORCE_PEER, - TDLS_CMD_STATS_UPDATE, - TDLS_CMD_CONFIG_UPDATE -}; - /** * struct tdls_conn_tracker_mac_table - connection tracker peer table * @mac_address: peer mac address diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4fc129ebea..bb5274fb52 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -37,6 +37,7 @@ #define WLAN_TDLS_PEER_SUB_LIST_SIZE 10 #define WLAN_MAC_MAX_EXTN_CAP 8 #define WLAN_MAC_MAX_SUPP_CHANNELS 100 +#define WLAN_MAC_WMI_MAX_SUPP_CHANNELS 128 #define WLAN_MAX_SUPP_OPER_CLASSES 32 #define WLAN_MAC_MAX_SUPP_RATES 32 #define WLAN_CHANNEL_14 14 @@ -46,6 +47,8 @@ #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36 +#define AC_PRIORITY_NUM 4 + /** Maximum time(ms) to wait for tdls add sta to complete **/ #define WAIT_TIME_TDLS_ADD_STA 1500 @@ -154,6 +157,30 @@ enum tdls_feature_mode { TDLS_SUPPORT_EXT_CONTROL, }; +/** + * enum tdls_command_type - TDLS command type + * @TDLS_CMD_TX_ACTION: send tdls action frame + * @TDLS_CMD_ADD_STA: add tdls peer + * @TDLS_CMD_CHANGE_STA: change tdls peer + * @TDLS_CMD_ENABLE_LINK: enable tdls link + * @TDLS_CMD_DISABLE_LINK: disable tdls link + * @TDLS_CMD_CONFIG_FORCE_PEER: config external peer + * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer + * @TDLS_CMD_STATS_UPDATE: update tdls stats + * @TDLS_CMD_CONFIG_UPDATE: config tdls + */ +enum tdls_command_type { + TDLS_CMD_TX_ACTION = 1, + TDLS_CMD_ADD_STA, + TDLS_CMD_CHANGE_STA, + TDLS_CMD_ENABLE_LINK, + TDLS_CMD_DISABLE_LINK, + TDLS_CMD_CONFIG_FORCE_PEER, + TDLS_CMD_REMOVE_FORCE_PEER, + TDLS_CMD_STATS_UPDATE, + TDLS_CMD_CONFIG_UPDATE +}; + /** * enum tdls_event_type - TDLS event type * @TDLS_EVENT_VDEV_STATE_CHANGE: umac connect/disconnect event @@ -676,7 +703,7 @@ struct tdls_peer_params { uint8_t peer_curr_operclass; uint8_t self_curr_operclass; uint8_t peer_chanlen; - struct tdls_ch_params peer_chan[WLAN_MAC_MAX_SUPP_CHANNELS]; + struct tdls_ch_params peer_chan[WLAN_MAC_WMI_MAX_SUPP_CHANNELS]; uint8_t peer_oper_classlen; uint8_t peer_oper_class[WLAN_MAX_SUPP_OPER_CLASSES]; uint8_t pref_off_channum; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 052f55b094..a3aa7b34a4 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -99,4 +99,15 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, struct tdls_update_peer_params *update_peer); + +/** + * ucfg_tdls_oper() - handle TDLS oper functions + * @vdev: vdev object + * @macaddr: MAC address of TDLS peer + * @cmd: oper cmd + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, + const uint8_t *macaddr, enum tdls_command_type cmd); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 045d99d1e9..c867af0274 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -332,3 +332,67 @@ dec_ref: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); return status; } + +static char *tdls_get_oper_str(enum tdls_command_type cmd_type) +{ + switch (cmd_type) { + case TDLS_CMD_ENABLE_LINK: + return "Enable_TDLS_LINK"; + case TDLS_CMD_DISABLE_LINK: + return "DISABLE_TDLS_LINK"; + case TDLS_CMD_REMOVE_FORCE_PEER: + return "REMOVE_FORCE_PEER"; + case TDLS_CMD_CONFIG_FORCE_PEER: + return "CONFIG_FORCE_PEER"; + default: + return "ERR:UNKNOWN OPER"; + } +} + +QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, + const uint8_t *macaddr, enum tdls_command_type cmd) +{ + struct scheduler_msg msg = {0,}; + struct tdls_oper_request *req; + QDF_STATUS status; + + if (!vdev || !macaddr) { + tdls_err("vdev: %p, mac %p", vdev, macaddr); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_debug("%s for peer " QDF_MAC_ADDRESS_STR, + tdls_get_oper_str(cmd), + QDF_MAC_ADDR_ARRAY(macaddr)); + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("%s: mem allocate fail", tdls_get_oper_str(cmd)); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto error; + } + + qdf_mem_copy(req->peer_addr, macaddr, QDF_MAC_ADDR_SIZE); + req->vdev = vdev; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = cmd; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post msg for %s fail", tdls_get_oper_str(cmd)); + goto dec_ref; + } + + return status; +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +error: + qdf_mem_free(req); + return status; +} From 57d308c33cb2a15017870b8c96fa1d5cf2bf1aab Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Thu, 16 Mar 2017 19:28:51 +0800 Subject: [PATCH 05/89] qcacmn: TDLS component: handle TDLS firmware event Handle TDLS related firmware event: tear down, discovery, disconnect, and send correspond indication to upper layer Change-Id: I6cff95904d06408f9458132ab5ce69f1a129e993 CRs-Fixed: 2011330 --- core/src/wlan_tdls_cmds_process.c | 238 ++++++++++++++++++++++++++++++ core/src/wlan_tdls_cmds_process.h | 30 ++++ core/src/wlan_tdls_main.c | 41 +++++ core/src/wlan_tdls_main.h | 5 + 4 files changed, 314 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 1c5d68454b..57e718d82d 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1611,3 +1611,241 @@ error: return status; } + +static const char *tdls_evt_to_str(enum tdls_event_msg_type type) +{ + switch (type) { + case TDLS_SHOULD_DISCOVER: + return "SHOULD_DISCOVER"; + case TDLS_SHOULD_TEARDOWN: + return "SHOULD_TEARDOWN"; + case TDLS_PEER_DISCONNECTED: + return "SHOULD_PEER_DISCONNECTED"; + case TDLS_CONNECTION_TRACKER_NOTIFY: + return "CONNECTION_TRACKER_NOTIFICATION"; + default: + return "INVALID_TYPE"; + } +} + +static void +tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *vdev_obj) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_peer *curr_peer, *temp_peer; + struct tdls_osif_indication ind; + + if (!vdev_obj) { + tdls_err("vdev_obj is NULL"); + return; + } + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj) { + tdls_err("soc_obj is NULL"); + return; + } + + curr_peer = vdev_obj->curr_candidate; + if (!curr_peer) { + tdls_err("curr_peer is NULL"); + return; + } + + temp_peer = tdls_is_progress(vdev_obj, NULL, 0); + if (temp_peer) { + tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + goto done; + } + + if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) + tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERING, + TDLS_LINK_SUCCESS); + + tdls_debug("Implicit TDLS, Send Discovery request event"); + + qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + ind.vdev = vdev_obj->vdev; + + if (soc_obj->tdls_event_cb) + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_DISCOVERY_REQ, &ind); + + vdev_obj->discovery_sent_cnt++; + /*TODO restart peer discovery timeout*/ + + tdls_debug("discovery count %u, timeout %u msec", + vdev_obj->discovery_sent_cnt, + vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); +done: + vdev_obj->curr_candidate = NULL; + vdev_obj->magic = 0; +} + +QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *curr_peer; + uint32_t feature; + uint16_t type; + + /*TODO ignore this if any concurrency detected*/ + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + type = evt->message_type; + + tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_evt_to_str(type), + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), + evt->peer_reason); + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + if (soc_obj->tdls_nss_switch_in_progress) { + tdls_err("TDLS antenna switching, ignore %s", + tdls_evt_to_str(type)); + return QDF_STATUS_SUCCESS; + } + + curr_peer = tdls_get_peer(vdev_obj, evt->peermac.bytes); + if (!curr_peer) { + tdls_notice("curr_peer is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (TDLS_LINK_CONNECTED == curr_peer->link_status) { + tdls_err("TDLS link status is connected, ignore"); + return QDF_STATUS_SUCCESS; + } + + feature = soc_obj->tdls_configs.tdls_feature_flags; + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature) && + !curr_peer->is_forced_peer) { + tdls_debug("curr_peer is not forced, ignore %s", + tdls_evt_to_str(type)); + return QDF_STATUS_SUCCESS; + } + + tdls_debug("initiate TDLS setup on %s, ext: %d, force: %d, reason: %d", + tdls_evt_to_str(type), + TDLS_IS_EXTERNAL_CONTROL_ENABLED(feature), + curr_peer->is_forced_peer, evt->peer_reason); + vdev_obj->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(vdev_obj); + + return QDF_STATUS_SUCCESS; +} + +static void +tdls_indicate_teardown(struct tdls_vdev_priv_obj *vdev_obj, + struct tdls_peer *curr_peer, uint16_t reason) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_osif_indication ind; + + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); + if (!soc_obj || !vdev_obj || !curr_peer) { + tdls_err("soc_obj: %p, vdev_obj: %p, curr_peer: %p", + soc_obj, vdev_obj, curr_peer); + return; + } + + if (TDLS_LINK_CONNECTED != curr_peer->link_status) { + tdls_debug("peer not connected"); + return; + } + + tdls_set_peer_link_status(curr_peer, TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + + tdls_debug("Teardown peer " QDF_MAC_ADDRESS_STR "reason %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), reason); + + qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + ind.reason = reason; + ind.vdev = vdev_obj->vdev; + + if (soc_obj->tdls_event_cb) + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &ind); +} + +QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_peer *curr_peer; + uint32_t reason; + uint16_t type; + + type = evt->message_type; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + + tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_evt_to_str(type), + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + + curr_peer = tdls_find_peer(vdev_obj, evt->peermac.bytes); + if (!curr_peer) { + tdls_notice("curr_peer is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + reason = evt->peer_reason; + if (TDLS_LINK_CONNECTED == curr_peer->link_status) { + tdls_err("%s reason: %d for" QDF_MAC_ADDRESS_STR, + tdls_evt_to_str(type), evt->peer_reason, + QDF_MAC_ADDR_ARRAY(evt->peermac.bytes)); + if (reason == TDLS_TEARDOWN_RSSI || + reason == TDLS_DISCONNECTED_PEER_DELETE || + reason == TDLS_TEARDOWN_PTR_TIMEOUT || + reason == TDLS_TEARDOWN_NO_RSP) + reason = TDLS_TEARDOWN_PEER_UNREACHABLE; + else + reason = TDLS_TEARDOWN_PEER_UNSPEC_REASON; + + tdls_indicate_teardown(vdev_obj, curr_peer, reason); + } else { + tdls_err("TDLS link is not connected, ignore %s", + tdls_evt_to_str(type)); + } + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt) +{ + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + uint16_t type; + + type = evt->message_type; + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + + if (!soc_obj || !vdev_obj) { + tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + soc_obj, vdev_obj, tdls_evt_to_str(type)); + return QDF_STATUS_E_NULL_VALUE; + } + + /*TODO connection tracker update*/ + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index ff643199b1..17201b7927 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -220,4 +220,34 @@ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); * Return: QDF status */ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp); + +/** + * tdls_process_should_discover() - handle tdls should_discover event + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); + +/** + * tdls_process_should_teardown() - handle tdls should_teardown event + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); + +/** + * tdls_process_connection_tracker_notify() -handle tdls connect tracker notify + * @vdev: vdev object + * @evt: event info + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, + struct tdls_event_info *evt); #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 4023edd5e4..a3409b80cf 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -239,3 +239,44 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) return status; } + +QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_event_notify *notify; + struct tdls_event_info *event; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: %p", msg); + return QDF_STATUS_E_NULL_VALUE; + } + notify = msg->bodyptr; + vdev = notify->vdev; + if (!vdev) { + tdls_err("NULL vdev object"); + qdf_mem_free(notify); + return QDF_STATUS_E_NULL_VALUE; + } + event = ¬ify->event; + + tdls_debug("evt type: %d", event->message_type); + switch (event->message_type) { + case TDLS_SHOULD_DISCOVER: + tdls_process_should_discover(vdev, event); + break; + case TDLS_SHOULD_TEARDOWN: + case TDLS_PEER_DISCONNECTED: + tdls_process_should_teardown(vdev, event); + break; + case TDLS_CONNECTION_TRACKER_NOTIFY: + tdls_process_connection_tracker_notify(vdev, event); + break; + default: + break; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + qdf_mem_free(notify); + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 0432502034..5087c905d9 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -49,6 +49,11 @@ #define TDLS_SEC_OFFCHAN_OFFSET_40MINUS (-40) #define TDLS_SEC_OFFCHAN_OFFSET_80 80 #define TDLS_SEC_OFFCHAN_OFFSET_160 160 +/* + * Before UpdateTimer expires, we want to timeout discovery response + * should not be more than 2000. + */ +#define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) From 502c3bcf6a173084983420f62ab63511ae82ffe7 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 29 Mar 2017 14:43:17 +0800 Subject: [PATCH 06/89] qcacmn: Enable TDLS component Enable TDLS module in dispatcher Change-Id: I4b1fe09278115a90eb6b19ed6ce8fef57143a910 CRs-Fixed: 2011330 --- dispatcher/inc/wlan_tdls_ucfg_api.h | 12 ++++++++++-- dispatcher/src/wlan_tdls_ucfg_api.c | 28 +++++++++++++++++++++++++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index a3aa7b34a4..70a6c450a2 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -73,12 +73,20 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, struct tdls_start_params *req); /** - * ucfg_tdls_psoc_stop() - TDLS module stop + * ucfg_tdls_psoc_enable() - TDLS module enable API * @psoc: psoc object * * Return: QDF_STATUS */ -QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc); +QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_psoc_disable() - TDLS moudle disable API + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc); /** * ucfg_tdls_add_peer() - handle TDLS add peer diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c867af0274..37a94d2495 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -23,6 +23,7 @@ */ #include +#include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" #include @@ -213,11 +214,32 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } -QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) +QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) { + QDF_STATUS status; + + tdls_notice("psoc tdls enable: 0x%p", psoc); + if (!psoc) { + tdls_err("NULL psoc"); + return QDF_STATUS_E_FAILURE; + } + + status = tgt_tdls_register_ev_handler(psoc); + + return status; +} + +QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj = NULL; - tdls_notice("tdls psoc stop"); + tdls_notice("psoc tdls disable: 0x%p", psoc); + if (!psoc) { + tdls_err("NULL psoc"); + return QDF_STATUS_E_FAILURE; + } + status = tgt_tdls_unregister_ev_handler(psoc); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { @@ -231,7 +253,7 @@ QDF_STATUS ucfg_tdls_psoc_stop(struct wlan_objmgr_psoc *psoc) soc_obj->tdls_tx_cnf_cb = NULL; soc_obj->tx_ack_cnf_cb_data = NULL; - return QDF_STATUS_SUCCESS; + return status; } QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) From 712cbfe634c6296e25e4468188f890388aa7ac94 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 27 Mar 2017 17:20:33 -0700 Subject: [PATCH 07/89] qcacmn: Add tdls timers function in tdls component Add tdls timers implemenation for discovery, idle and connection tracker. Change-Id: I7ccd5ec6c1d396a0fd25e6f28a258986a646c800 CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 75 +++++++++++++++++++++++++++++++++++++++ core/src/wlan_tdls_main.h | 21 +++++++++++ 2 files changed, 96 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a3409b80cf..d48134e5c5 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -280,3 +280,78 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } + +void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, + qdf_mc_timer_t *timer, + uint32_t expiration_time) +{ + qdf_mc_timer_stop(timer); + qdf_mc_timer_start(timer, expiration_time); +} + +/** + * wlan_hdd_tdls_monitor_timers_stop() - stop all monitoring timers + * @hdd_tdls_ctx: TDLS context + * + * Return: none + */ +static void tdls_monitor_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); +} + +/** + * tdls_peer_idle_timers_stop() - stop peer idle timers + * @tdls_vdev: TDLS vdev object + * + * Loop through the idle peer list and stop their timers + * + * Return: None + */ +static void tdls_peer_idle_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + QDF_STATUS status; + + tdls_vdev->discovery_peer_cnt = 0; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, struct tdls_peer, + node); + if (curr_peer->is_peer_idle_timer_initialised) + qdf_mc_timer_stop(&curr_peer->peer_idle_timer); + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + +} + +/** + * wlan_hdd_tdls_ct_timers_stop() - stop tdls connection tracker timers + * @tdls_vdev: TDLS vdev + * + * Return: None + */ +static void tdls_ct_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + qdf_mc_timer_stop(&tdls_vdev->peer_update_timer); + tdls_peer_idle_timers_stop(tdls_vdev); +} + +/** + * wlan_hdd_tdls_timers_stop() - stop all the tdls timers running + * @tdls_vdev: TDLS vdev + * + * Return: none + */ +void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_monitor_timers_stop(tdls_vdev); + tdls_ct_timers_stop(tdls_vdev); +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 5087c905d9..391ccbf92a 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -454,4 +454,25 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg); * Return: QDF_STATUS */ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg); + +/** + * tdls_timer_restart() - restart TDLS timer + * @vdev: VDEV object manager + * @timer: timer to restart + * @expiration_time: new expiration time to set for the timer + * + * Return: Void + */ +void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, + qdf_mc_timer_t *timer, + uint32_t expiration_time); + +/** + * wlan_hdd_tdls_timers_stop() - stop all the tdls timers running + * @tdls_vdev: TDLS vdev + * + * Return: none + */ +void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev); + #endif From 00619ab3b873bed1fc9034a709d77485576975f6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 20 Mar 2017 01:59:24 -0700 Subject: [PATCH 08/89] qcacmn: Add connection tracker to TDLS UMAC Add connection tracker support in TDLS UMAC component Change-Id: I725b579ab9f393d5247651bfe53df6b4a3f53649 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 93 +-- core/src/wlan_tdls_ct.c | 894 ++++++++++++++++++++++++++++ core/src/wlan_tdls_ct.h | 137 ++++- core/src/wlan_tdls_main.c | 36 +- core/src/wlan_tdls_main.h | 26 + dispatcher/src/wlan_tdls_ucfg_api.c | 18 + 6 files changed, 1108 insertions(+), 96 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 57e718d82d..dacabe74a4 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -25,6 +25,7 @@ #include #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" @@ -1628,63 +1629,6 @@ static const char *tdls_evt_to_str(enum tdls_event_msg_type type) } } -static void -tdls_implicit_send_discovery_request(struct tdls_vdev_priv_obj *vdev_obj) -{ - struct tdls_soc_priv_obj *soc_obj; - struct tdls_peer *curr_peer, *temp_peer; - struct tdls_osif_indication ind; - - if (!vdev_obj) { - tdls_err("vdev_obj is NULL"); - return; - } - - soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); - if (!soc_obj) { - tdls_err("soc_obj is NULL"); - return; - } - - curr_peer = vdev_obj->curr_candidate; - if (!curr_peer) { - tdls_err("curr_peer is NULL"); - return; - } - - temp_peer = tdls_is_progress(vdev_obj, NULL, 0); - if (temp_peer) { - tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", - QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); - goto done; - } - - if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) - tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERING, - TDLS_LINK_SUCCESS); - - tdls_debug("Implicit TDLS, Send Discovery request event"); - - qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, - QDF_MAC_ADDR_SIZE); - ind.vdev = vdev_obj->vdev; - - if (soc_obj->tdls_event_cb) - soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, - TDLS_EVENT_DISCOVERY_REQ, &ind); - - vdev_obj->discovery_sent_cnt++; - /*TODO restart peer discovery timeout*/ - - tdls_debug("discovery count %u, timeout %u msec", - vdev_obj->discovery_sent_cnt, - vdev_obj->threshold_config.tx_period_t - - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE); -done: - vdev_obj->curr_candidate = NULL; - vdev_obj->magic = 0; -} - QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt) { @@ -1743,41 +1687,6 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } -static void -tdls_indicate_teardown(struct tdls_vdev_priv_obj *vdev_obj, - struct tdls_peer *curr_peer, uint16_t reason) -{ - struct tdls_soc_priv_obj *soc_obj; - struct tdls_osif_indication ind; - - soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); - if (!soc_obj || !vdev_obj || !curr_peer) { - tdls_err("soc_obj: %p, vdev_obj: %p, curr_peer: %p", - soc_obj, vdev_obj, curr_peer); - return; - } - - if (TDLS_LINK_CONNECTED != curr_peer->link_status) { - tdls_debug("peer not connected"); - return; - } - - tdls_set_peer_link_status(curr_peer, TDLS_LINK_TEARING, - TDLS_LINK_UNSPECIFIED); - - tdls_debug("Teardown peer " QDF_MAC_ADDRESS_STR "reason %d", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), reason); - - qdf_mem_copy(ind.peer_mac, curr_peer->peer_mac.bytes, - QDF_MAC_ADDR_SIZE); - ind.reason = reason; - ind.vdev = vdev_obj->vdev; - - if (soc_obj->tdls_event_cb) - soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, - TDLS_EVENT_TEARDOWN_REQ, &ind); -} - QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt) { diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 851d0a1999..52ccfcfd20 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -21,3 +21,897 @@ * * TDLS connection tracker function definitions */ + +#include "wlan_tdls_main.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" + +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_peer *peer; + enum wlan_peer_state peer_state; + + wlan_vdev_obj_lock(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + wlan_vdev_obj_unlock(vdev); + + if (!peer) { + tdls_err("peer is null"); + return false; + } + + wlan_peer_obj_lock(peer); + peer_state = wlan_peer_mlme_get_state(peer); + wlan_peer_obj_unlock(peer); + + if (peer_state != WLAN_ASSOC_STATE) { + tdls_err("peer state: %d", peer_state); + return false; + } + + return true; +} + +/** + * tdls_peer_reset_discovery_processed() - reset discovery status + * @tdls_vdev: TDLS vdev object + * + * This function resets discovery processing bit for all TDLS peers + * + * Caller has to take the lock before calling this function + * + * Return: 0 + */ +static int32_t tdls_peer_reset_discovery_processed( + struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + + tdls_vdev->discovery_peer_cnt = 0; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + peer->discovery_processed = 0; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + return 0; +} + +void tdls_discovery_timeout_peer_cb(void *user_data) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev; + + if (!user_data) { + tdls_err("discovery time out data is null"); + return; + } + + tdls_vdev = (struct tdls_vdev_priv_obj *) user_data; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, + node); + if (TDLS_LINK_DISCOVERING != peer->link_status) { + status = qdf_list_peek_next(head, p_node, + &p_node); + continue; + } + tdls_debug(QDF_MAC_ADDRESS_STR " to idle state", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_set_peer_link_status(peer, + TDLS_LINK_IDLE, + TDLS_LINK_NOT_SUPPORTED); + } + } + tdls_vdev->discovery_sent_cnt = 0; + + /* add tdls power save prohibited */ + + return; +} + +/** + * tdls_reset_tx_rx() - reset tx/rx counters for all tdls peers + * @tdls_vdev: TDLS vdev object + * + * Caller has to take the TDLS lock before calling this function + * + * Return: Void + */ +static void tdls_reset_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *peer; + QDF_STATUS status; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + peer = qdf_container_of(p_node, struct tdls_peer, node); + peer->tx_pkt = 0; + peer->rx_pkt = 0; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + return; +} + +void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_debug("Disable Implicit TDLS"); + tdls_timers_stop(tdls_vdev); +} + +/** + * tdls_implicit_enable() - enable implicit tdls triggering + * @tdls_vdev: TDLS vdev + * + * Return: Void + */ +void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev) +{ + tdls_debug("Enable Implicit TDLS"); + if (!tdls_vdev) + return; + + tdls_peer_reset_discovery_processed(tdls_vdev); + tdls_reset_tx_rx(tdls_vdev); + /* TODO check whether tdls power save prohibited */ + + /* Restart the connection tracker timer */ + tdls_timer_restart(tdls_vdev->vdev, &tdls_vdev->peer_update_timer, + tdls_vdev->threshold_config.tx_period_t); +} + +/** + * tdls_ct_sampling_tx_rx() - collect tx/rx traffic sample + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function to update data traffic information in tdls connection + * tracker data structure for connection tracker operation + * + * Return: None + */ +static void tdls_ct_sampling_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + struct tdls_peer *curr_peer; + uint8_t mac[QDF_MAC_ADDR_SIZE]; + uint8_t mac_cnt; + uint8_t mac_entries; + struct tdls_conn_tracker_mac_table mac_table[WLAN_TDLS_CT_TABLE_SIZE]; + + qdf_spin_lock_bh(&tdls_soc->tdls_ct_spinlock); + + if (0 == tdls_vdev->valid_mac_entries) { + qdf_spin_unlock_bh(&tdls_soc->tdls_ct_spinlock); + return; + } + + mac_entries = tdls_vdev->valid_mac_entries; + + qdf_mem_copy(mac_table, tdls_vdev->ct_peer_table, + (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); + + qdf_mem_set(tdls_vdev->ct_peer_table, 0, + (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); + + tdls_vdev->valid_mac_entries = 0; + + qdf_spin_unlock_bh(&tdls_soc->tdls_ct_spinlock); + + for (mac_cnt = 0; mac_cnt < mac_entries; mac_cnt++) { + qdf_mem_copy(mac, mac_table[mac_cnt].mac_address.bytes, + QDF_MAC_ADDR_SIZE); + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (NULL != curr_peer) { + curr_peer->tx_pkt = + mac_table[mac_cnt].tx_packet_cnt; + curr_peer->rx_pkt = + mac_table[mac_cnt].rx_packet_cnt; + } + } +} + +void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t mac_cnt; + uint8_t valid_mac_entries; + struct tdls_conn_tracker_mac_table *mac_table; + + tdls_debug("enter "); + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + if (!tdls_soc_obj->enable_tdls_connection_tracker) + return; + + if (qdf_is_macaddr_group(mac_addr)) + return; + + if (qdf_mem_cmp(vdev->vdev_mlme.macaddr, mac_addr, + QDF_MAC_ADDR_SIZE) == 0) + return; + + qdf_spin_lock_bh(&tdls_soc_obj->tdls_ct_spinlock); + valid_mac_entries = tdls_vdev_obj->valid_mac_entries; + mac_table = tdls_vdev_obj->ct_peer_table; + + for (mac_cnt = 0; mac_cnt < valid_mac_entries; mac_cnt++) { + if (qdf_mem_cmp(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE) == 0) { + mac_table[mac_cnt].rx_packet_cnt++; + goto rx_cnt_return; + } + } + + /* If we have more than 8 peers within 30 mins. we will + * stop tracking till the old entries are removed + */ + if (mac_cnt < WLAN_TDLS_CT_TABLE_SIZE) { + qdf_mem_copy(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE); + tdls_vdev_obj->valid_mac_entries = mac_cnt+1; + mac_table[mac_cnt].rx_packet_cnt = 1; + } + +rx_cnt_return: + qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); + tdls_debug("exit: rx pkt count %d ", mac_table[mac_cnt].rx_packet_cnt); + return; +} + +void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t mac_cnt; + uint8_t valid_mac_entries; + struct tdls_conn_tracker_mac_table *mac_table; + + tdls_debug("enter "); + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + if (!tdls_soc_obj->enable_tdls_connection_tracker) + return; + + if (qdf_is_macaddr_group(mac_addr)) + return; + + if (qdf_mem_cmp(vdev->vdev_mlme.macaddr, mac_addr, + QDF_MAC_ADDR_SIZE) == 0) + return; + + qdf_spin_lock_bh(&tdls_soc_obj->tdls_ct_spinlock); + mac_table = tdls_vdev_obj->ct_peer_table; + + valid_mac_entries = tdls_vdev_obj->valid_mac_entries; + + for (mac_cnt = 0; mac_cnt < valid_mac_entries; mac_cnt++) { + if (qdf_mem_cmp(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE) == 0) { + mac_table[mac_cnt].tx_packet_cnt++; + goto tx_cnt_return; + } + } + + /* If we have more than 8 peers within 30 mins. we will + * stop tracking till the old entries are removed + */ + if (mac_cnt < WLAN_TDLS_CT_TABLE_SIZE) { + qdf_mem_copy(mac_table[mac_cnt].mac_address.bytes, + mac_addr, QDF_MAC_ADDR_SIZE); + mac_table[mac_cnt].tx_packet_cnt = 1; + tdls_vdev_obj->valid_mac_entries++; + } + +tx_cnt_return: + qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); + tdls_debug("exit: tx pkt count %d", mac_table[mac_cnt].tx_packet_cnt); + return; +} + +void tdls_implicit_send_discovery_request( + struct tdls_vdev_priv_obj *tdls_vdev_obj) +{ + struct tdls_peer *curr_peer; + struct tdls_peer *temp_peer; + struct tdls_soc_priv_obj *tdls_psoc; + struct tdls_osif_indication tdls_ind; + + if (NULL == tdls_vdev_obj) { + tdls_notice("tdls_vdev_obj is NULL"); + return; + } + + tdls_psoc = wlan_vdev_get_tdls_soc_obj(tdls_vdev_obj->vdev); + + if (NULL == tdls_psoc) { + tdls_notice("tdls_psoc_obj is NULL"); + return; + } + + curr_peer = tdls_vdev_obj->curr_candidate; + + if (NULL == curr_peer) { + tdls_err("curr_peer is NULL"); + return; + } + + /* This function is called in mutex_lock */ + temp_peer = tdls_is_progress(tdls_vdev_obj, NULL, 0); + if (NULL != temp_peer) { + tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + goto done; + } + + if (TDLS_CAP_UNKNOWN != curr_peer->tdls_support) + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_DISCOVERING, + TDLS_LINK_SUCCESS); + + qdf_mem_copy(tdls_ind.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + + tdls_ind.vdev = tdls_vdev_obj->vdev; + + tdls_debug("Implicit TDLS, Send Discovery request event"); + + tdls_psoc->tdls_event_cb(tdls_psoc->tdls_evt_cb_data, + TDLS_EVENT_DISCOVERY_REQ, &tdls_ind); + + tdls_vdev_obj->discovery_sent_cnt++; + + tdls_timer_restart(tdls_vdev_obj->vdev, + &tdls_vdev_obj->peer_discovery_timer, + tdls_vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE); + + tdls_debug("discovery count %u timeout %u msec", + tdls_vdev_obj->discovery_sent_cnt, + tdls_vdev_obj->threshold_config.tx_period_t - + TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE); +done: + tdls_vdev_obj->curr_candidate = NULL; + tdls_vdev_obj->magic = 0; + return; +} + +int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac) +{ + struct tdls_peer *curr_peer; + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_osif_indication indication; + struct tdls_config_params *tdls_cfg; + int status = 0; + + if (!tdls_vdev) + return -EINVAL; + + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); + if (NULL == tdls_soc) { + tdls_err("tdls soc is NULL"); + return -EINVAL; + } + + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (NULL == curr_peer) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + if (tdls_vdev->discovery_sent_cnt) + tdls_vdev->discovery_sent_cnt--; + + if (0 == tdls_vdev->discovery_sent_cnt) + qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); + + tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDRESS_STR + " link_status %d", tdls_vdev->discovery_sent_cnt, + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->link_status); + + tdls_cfg = &tdls_vdev->threshold_config; + if (TDLS_LINK_DISCOVERING == curr_peer->link_status) { + /* Since we are here, it means Throughput threshold is + * already met. Make sure RSSI threshold is also met + * before setting up TDLS link. + */ + if ((int32_t) curr_peer->rssi > + (int32_t) tdls_cfg->rssi_trigger_threshold) { + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_DISCOVERED, + TDLS_LINK_SUCCESS); + tdls_debug("Rssi Threshold met: " QDF_MAC_ADDRESS_STR + " rssi = %d threshold= %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->rssi, + tdls_cfg->rssi_trigger_threshold); + + qdf_mem_copy(indication.peer_mac, mac, + QDF_MAC_ADDR_SIZE); + + indication.vdev = tdls_vdev->vdev; + + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_SETUP_REQ, + &indication); + } else { + tdls_debug("Rssi Threshold not met: " + QDF_MAC_ADDRESS_STR + " rssi = %d threshold = %d ", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->rssi, + tdls_cfg->rssi_trigger_threshold); + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + + /* if RSSI threshold is not met then allow + * further discovery attempts by decrementing + * count for the last attempt + */ + if (curr_peer->discovery_attempt) + curr_peer->discovery_attempt--; + } + } + + curr_peer->tdls_support = TDLS_CAP_SUPPORTED; + + return status; +} + +void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_peer *curr_peer, + uint16_t reason) +{ + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_osif_indication indication; + + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); + if (!tdls_soc || !tdls_vdev || !curr_peer) { + tdls_err("tdls_soc: %p, tdls_vdev: %p, curr_peer: %p", + tdls_soc, tdls_vdev, curr_peer); + return; + } + + if (TDLS_LINK_CONNECTED != curr_peer->link_status) + return; + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_TEARING, + TDLS_LINK_UNSPECIFIED); + tdls_notice("Teardown reason %d", reason); + + indication.reason = reason; + indication.vdev = tdls_vdev->vdev; + qdf_mem_copy(indication.peer_mac, curr_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + + if (tdls_soc->tdls_event_cb) + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_REQ, &indication); +} + +/** + * tdls_get_conn_info() - get the tdls connection information. + * @tdls_soc: tdls soc object + * @idx: sta id + * + * Function to check tdls sta index + * + * Return: tdls connection information + */ +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); + return &tdls_soc->tdls_conn_info[sta_idx]; + } + } + + tdls_err("tdls peer with staIdx %u not exists", idx); + return NULL; +} + +static void +tdls_ct_process_idle_handler( + struct tdls_ct_idle_peer_data *tdls_idle_peer_data) +{ + 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; + + if (!tdls_info->sta_id) { + tdls_err("peer (staidx %u) doesn't exists", tdls_info->sta_id); + return; + } + + curr_peer = tdls_find_peer(tdls_vdev_obj, + (u8 *) &tdls_info->peer_mac.bytes[0]); + + if (NULL == curr_peer) { + tdls_err("Invalid tdls idle timer expired"); + return; + } + + tdls_debug(QDF_MAC_ADDRESS_STR + " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->tx_pkt, + curr_peer->rx_pkt, + tdls_vdev_obj->threshold_config.idle_packet_n); + + /* Check tx/rx statistics on this tdls link for recent activities and + * then decide whether to tear down the link or keep it. + */ + if ((curr_peer->tx_pkt >= + tdls_vdev_obj->threshold_config.idle_packet_n) || + (curr_peer->rx_pkt >= + tdls_vdev_obj->threshold_config.idle_packet_n)) { + /* this tdls link got back to normal, so keep it */ + tdls_debug("tdls link to " QDF_MAC_ADDRESS_STR + " back to normal, will stay", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + } else { + /* this tdls link needs to get torn down */ + tdls_notice("trigger tdls link to "QDF_MAC_ADDRESS_STR" down", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_indicate_teardown(tdls_vdev_obj, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + } + + return; +} + +void tdls_ct_idle_handler(void *user_data) +{ + struct tdls_ct_idle_peer_data *tdls_idle_peer_data; + struct wlan_objmgr_vdev *vdev; + + 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) + return; + + vdev = tdls_idle_peer_data->vdev; + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_ct_process_idle_handler(tdls_idle_peer_data); + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); +} + +/** + * tdls_ct_process_idle_and_discovery() - process the traffic data + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function to check the peer traffic data in idle link and tdls + * discovering link + * + * Return: None + */ +static void +tdls_ct_process_idle_and_discovery(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + uint16_t valid_peers; + + valid_peers = tdls_soc_obj->connected_peer_count; + + if ((curr_peer->tx_pkt + curr_peer->rx_pkt) >= + tdls_vdev_obj->threshold_config.tx_packet_n) { + if (WLAN_TDLS_STA_MAX_NUM > valid_peers) { + tdls_notice("Tput trigger TDLS pre-setup"); + tdls_vdev_obj->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(tdls_vdev_obj); + } else { + tdls_notice("Maximum peers connected already! %d", + valid_peers); + } + } +} + +/** + * tdls_ct_process_connected_link() - process the traffic + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev + * @tdls_soc_obj: tdls soc context + * + * Function to check the peer traffic data in active STA + * session + * + * Return: None + */ +static void tdls_ct_process_connected_link( + struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + + if ((int32_t)curr_peer->rssi < + (int32_t)tdls_vdev->threshold_config.rssi_teardown_threshold) { + tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + return; + } + + /* Only teardown based on non zero idle packet threshold, to address + * a use case where this threshold does not get consider for TEAR DOWN + */ + if ((0 != tdls_vdev->threshold_config.idle_packet_n) && + ((curr_peer->tx_pkt < + tdls_vdev->threshold_config.idle_packet_n) && + (curr_peer->rx_pkt < + tdls_vdev->threshold_config.idle_packet_n))) { + if (!curr_peer->is_peer_idle_timer_initialised) { + 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); + curr_peer->is_peer_idle_timer_initialised = true; + } + if (QDF_TIMER_STATE_RUNNING != + curr_peer->peer_idle_timer.state) { + tdls_warn("Tx/Rx Idle timer start: " + QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + tdls_timer_restart(tdls_vdev->vdev, + &curr_peer->peer_idle_timer, + tdls_vdev->threshold_config.idle_timeout_t); + } + } else if (QDF_TIMER_STATE_RUNNING == + curr_peer->peer_idle_timer.state) { + tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); + qdf_mc_timer_stop(&curr_peer->peer_idle_timer); + } +} + +/** + * tdls_ct_process_cap_supported() - process TDLS supported peer. + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev context + * @tdls_soc_obj: tdls soc context + * + * Function to check the peer traffic data for tdls supported peer + * + * Return: None + */ +static void tdls_ct_process_cap_supported(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_debug("tx %d rx %d thr.pkt %d/idle %d rssi %d thr.trig %d/tear %d", + curr_peer->tx_pkt, curr_peer->rx_pkt, + tdls_vdev->threshold_config.tx_packet_n, + tdls_vdev->threshold_config.idle_packet_n, + curr_peer->rssi, + tdls_vdev->threshold_config.rssi_trigger_threshold, + tdls_vdev->threshold_config.rssi_teardown_threshold); + + switch (curr_peer->link_status) { + case TDLS_LINK_IDLE: + case TDLS_LINK_DISCOVERING: + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags) && + (!curr_peer->is_forced_peer)) + break; + tdls_ct_process_idle_and_discovery(curr_peer, tdls_vdev, + tdls_soc_obj); + break; + case TDLS_LINK_CONNECTED: + tdls_ct_process_connected_link(curr_peer, tdls_vdev, + tdls_soc_obj); + break; + default: + break; + } +} + +/** + * tdls_ct_process_cap_unknown() - process unknown peer + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Function check the peer traffic data , when tdls capability is unknown + * + * Return: None + */ +static void tdls_ct_process_cap_unknown(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdlsa_soc) +{ + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdlsa_soc->tdls_configs.tdls_feature_flags) && + (!curr_peer->is_forced_peer)) + return; + + tdls_debug("threshold tx pkt = %d peer tx_pkt = %d & rx_pkt = %d ", + tdls_vdev->threshold_config.tx_packet_n, curr_peer->tx_pkt, + curr_peer->rx_pkt); + + if (!TDLS_IS_LINK_CONNECTED(curr_peer) && + ((curr_peer->tx_pkt + curr_peer->rx_pkt) >= + tdls_vdev->threshold_config.tx_packet_n)) { + /* Ignore discovery attempt if External Control is enabled, that + * is, peer is forced. In that case, continue discovery attempt + * regardless attempt count + */ + tdls_debug("TDLS UNKNOWN pre discover "); + if (curr_peer->is_forced_peer || + curr_peer->discovery_attempt++ < + tdls_vdev->threshold_config.discovery_tries_n) { + tdls_debug("TDLS UNKNOWN discover "); + tdls_vdev->curr_candidate = curr_peer; + tdls_implicit_send_discovery_request(tdls_vdev); + } else { + curr_peer->tdls_support = TDLS_CAP_NOT_SUPPORTED; + tdls_set_peer_link_status( + curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_NOT_SUPPORTED); + } + } +} + +/** + * tdls_ct_process_peers() - process the peer + * @curr_peer: tdls peer needs to be examined + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * This function check the peer capability and process the metadata from + * the peer + * + * Return: None + */ +static void tdls_ct_process_peers(struct tdls_peer *curr_peer, + struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_debug(QDF_MAC_ADDRESS_STR " link_status %d tdls_support %d", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->link_status, curr_peer->tdls_support); + + switch (curr_peer->tdls_support) { + case TDLS_CAP_SUPPORTED: + tdls_ct_process_cap_supported(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + break; + + case TDLS_CAP_UNKNOWN: + tdls_ct_process_cap_unknown(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + break; + default: + break; + } + +} + +static void tdls_ct_process_handler(struct wlan_objmgr_vdev *vdev) +{ + int i; + qdf_list_t *head; + qdf_list_node_t *list_node; + struct tdls_peer *curr_peer; + QDF_STATUS status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) + return; + + /* If any concurrency is detected */ + if (!tdls_soc_obj->enable_tdls_connection_tracker) { + tdls_notice("Connection tracker is disabled"); + return; + } + + /* Update tx rx traffic sample in tdls data structures */ + tdls_ct_sampling_tx_rx(tdls_vdev_obj, tdls_soc_obj); + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev_obj->peer_list[i]; + status = qdf_list_peek_front(head, &list_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(list_node, + struct tdls_peer, node); + tdls_ct_process_peers(curr_peer, tdls_vdev_obj, + tdls_soc_obj); + curr_peer->tx_pkt = 0; + curr_peer->rx_pkt = 0; + status = qdf_list_peek_next(head, + list_node, &list_node); + } + } + + tdls_timer_restart(tdls_vdev_obj->vdev, + &tdls_vdev_obj->peer_update_timer, + tdls_vdev_obj->threshold_config.tx_period_t); + +} + +void tdls_ct_handler(void *user_data) +{ + struct wlan_objmgr_vdev *vdev; + + if (!user_data) + return; + + vdev = (struct wlan_objmgr_vdev *)user_data; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_ct_process_handler(vdev); + + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); +} + diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 473f2b5566..d894794eb5 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -19,5 +19,140 @@ /** * DOC: wlan_tdls_ct.h * - * TDLS connection tracker api declaration + * TDLS connection tracker declarations */ + +#ifndef _WLAN_TDLS_CT_H_ +#define _WLAN_TDLS_CT_H_ + + /* + * Before UpdateTimer expires, we want to timeout discovery response + * should not be more than 2000. + */ +#define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000 + +/** + * tdls_is_vdev_connected() - check the vdev is connected to ap + * @vdev: vdev object manager + * + * This function will check the vdev connection status and return + * true or false + * + * Return: true - Connected, false - Not connected + */ +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_implicit_enable() - enable implicit tdls triggering + * @tdls_vdev: TDLS vdev + * + * Return: Void + */ +void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev); + +/** + * tdls_update_rx_pkt_cnt() - Update rx packet count + * @vdev: vdev object manager + * @mac_addr: mac address of the data + * + * Increase the rx packet count, if the sender is not bssid and the packet is + * not broadcast and muticast packet + * + * This sampling information will be used in TDLS connection tracker + * + * This function expected to be called in an atomic context so blocking APIs + * not allowed + * + * Return: None + */ +void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * tdls_update_tx_pkt_cnt() - update tx packet + * @vdev: vdev object + * @mac_addr: mac address of the data + * + * Increase the tx packet count, if the sender is not bssid and the packet is + * not broadcast and muticast packet + * + * This sampling information will be used in TDLS connection tracker + * + * This function expected to be called in an atomic context so blocking APIs + * not allowed + * + * Return: None + */ +void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * wlan_hdd_tdls_implicit_send_discovery_request() - send discovery request + * @tdls_vdev_obj: tdls vdev object + * + * Return: None + */ +void tdls_implicit_send_discovery_request( + struct tdls_vdev_priv_obj *tdls_vdev_obj); + +/** + * tdls_recv_discovery_resp() - handling of tdls discovery response + * @soc: object manager + * @mac: mac address of peer from which the response was received + * + * Return: 0 for success or negative errno otherwise + */ +int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac); + +/** + * tdls_indicate_teardown() - indicate teardown to upper layer + * @tdls_vdev: tdls vdev object + * @curr_peer: teardown peer + * @reason: teardown reason + * + * Return: Void + */ +void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_peer *curr_peer, + uint16_t reason); + +/** + * tdls_ct_handler() - TDLS connection tracker handler + * @user_data: user data from timer + * + * tdls connection tracker timer starts, when the STA connected to AP + * and it's scan the traffic between two STA peers and make TDLS + * connection and teardown, based on the traffic threshold + * + * Return: None + */ +void tdls_ct_handler(void *user_data); + +/** + * tdls_ct_idle_handler() - Check tdls idle traffic + * @user_data: data from tdls idle timer + * + * Function to check the tdls idle traffic and make a decision about + * tdls teardown + * + * Return: None + */ +void tdls_ct_idle_handler(void *user_data); + +/** + * tdls_discovery_timeout_peer_cb() - tdls discovery timeout callback + * @userData: tdls vdev + * + * Return: None + */ +void tdls_discovery_timeout_peer_cb(void *user_data); + +/** + * tdls_implicit_disable() - disable implicit tdls triggering + * @pHddTdlsCtx: TDLS context + * + * Return: Void + */ +void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); +#endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d48134e5c5..e07ffcec7b 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -25,6 +25,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -111,9 +112,10 @@ static QDF_STATUS tdls_vdev_init(struct tdls_vdev_priv_obj *vdev_obj) WLAN_TDLS_PEER_SUB_LIST_SIZE); } qdf_mc_timer_init(&vdev_obj->peer_update_timer, QDF_TIMER_TYPE_SW, - NULL, vdev_obj); + tdls_ct_handler, vdev_obj->vdev); qdf_mc_timer_init(&vdev_obj->peer_discovery_timer, QDF_TIMER_TYPE_SW, - NULL, vdev_obj); + tdls_discovery_timeout_peer_cb, vdev_obj); + return QDF_STATUS_SUCCESS; } @@ -247,7 +249,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) struct tdls_event_info *event; if (!msg || !msg->bodyptr) { - tdls_err("msg: %p", msg); + tdls_err("msg is not valid: %p", msg); return QDF_STATUS_E_NULL_VALUE; } notify = msg->bodyptr; @@ -355,3 +357,31 @@ void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev) tdls_monitor_timers_stop(tdls_vdev); tdls_ct_timers_stop(tdls_vdev); } + +QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, + struct tdls_vdev_priv_obj **tdls_vdev_obj, + struct tdls_soc_priv_obj **tdls_soc_obj) +{ + enum tQDF_ADAPTER_MODE device_mode; + + if (NULL == vdev) + return QDF_STATUS_E_FAILURE; + + *tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (NULL == (*tdls_vdev_obj)) + return QDF_STATUS_E_FAILURE; + + *tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (NULL == (*tdls_soc_obj)) + return QDF_STATUS_E_FAILURE; + + wlan_vdev_obj_lock(vdev); + device_mode = wlan_vdev_mlme_get_opmode(vdev); + wlan_vdev_obj_unlock(vdev); + + if (device_mode != QDF_STA_MODE && + device_mode != QDF_P2P_CLIENT_MODE) + return QDF_STATUS_E_FAILURE; + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 391ccbf92a..cf758e772e 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -116,6 +116,16 @@ 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: @@ -164,6 +174,8 @@ struct tdls_set_state_info { * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_idle_peer_data: provide information about idle peer + * @tdls_ct_spinlock: connection tracker spin lock */ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; @@ -196,6 +208,8 @@ struct tdls_soc_priv_obj { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + struct tdls_ct_idle_peer_data tdls_idle_peer_data; + qdf_spinlock_t tdls_ct_spinlock; }; /** @@ -475,4 +489,16 @@ void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, */ void tdls_timers_stop(struct tdls_vdev_priv_obj *tdls_vdev); +/** + * tdls_get_vdev_objects() - Get TDLS private objects + * @vdev: VDEV object manager + * @tdls_vdev_obj: tdls vdev object + * @tdls_soc_obj: tdls soc object + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, + struct tdls_vdev_priv_obj **tdls_vdev_obj, + struct tdls_soc_priv_obj **tdls_soc_obj); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 37a94d2495..7a557a3df2 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -142,7 +142,16 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) } soc_obj->enable_tdls_connection_tracker = false; soc_obj->tdls_external_peer_count = 0; + soc_obj->tdls_disable_in_progress = false; + qdf_spinlock_create(&soc_obj->tdls_ct_spinlock); + + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_global_deinit(struct tdls_soc_priv_obj *soc_obj) +{ + qdf_spinlock_destroy(&soc_obj->tdls_ct_spinlock); return QDF_STATUS_SUCCESS; } @@ -259,8 +268,17 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_STATUS ucfg_tdls_psoc_close(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_soc_priv_obj *tdls_soc; tdls_notice("tdls psoc close"); + tdls_soc = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (!tdls_soc) { + tdls_err("Failed to get tdls psoc component"); + return QDF_STATUS_E_FAILURE; + } + + status = tdls_global_deinit(tdls_soc); return status; } From 61442d253b3f15cbcc01ef1ecc7fd97f0d761ef7 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:19:19 -0700 Subject: [PATCH 09/89] qcacmn: Add TDLS management frames Add TDLS management frames implementaion in TDLS umac component Change-Id: I46943f7df119894e0d54df2c6edb08ed4546a389 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 1 + core/src/wlan_tdls_cmds_process.h | 9 + core/src/wlan_tdls_main.c | 2 + core/src/wlan_tdls_mgmt.c | 407 ++++++++++++++++++++++ core/src/wlan_tdls_mgmt.h | 51 +++ dispatcher/inc/wlan_tdls_public_structs.h | 40 +++ dispatcher/inc/wlan_tdls_ucfg_api.h | 12 + dispatcher/src/wlan_tdls_ucfg_api.c | 39 +++ 8 files changed, 561 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index dacabe74a4..49784df9bd 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -26,6 +26,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_mgmt.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 17201b7927..32e8cba01a 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -250,4 +250,13 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, struct tdls_event_info *evt); + +/** + * tdls_validate_mgmt_request() -validate mgmt request + * @tdls_validate: action frame request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e07ffcec7b..b4b28c0b83 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -26,6 +26,7 @@ #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_mgmt.h" QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -212,6 +213,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) switch (msg->type) { case TDLS_CMD_TX_ACTION: + tdls_process_mgmt_req(msg->bodyptr); break; case TDLS_CMD_ADD_STA: tdls_process_add_peer(msg->bodyptr); diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index a8e5f87980..3f28bf0817 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -21,3 +21,410 @@ * * TDLS management frames implementation */ + +#include "wlan_tdls_main.h" +#include "wlan_tdls_tgt_api.h" +#include +#include "wlan_mgmt_txrx_utils_api.h" +#include "wlan_tdls_peer.h" +#include "wlan_tdls_ct.h" +#include "wlan_tdls_cmds_process.h" +#include "wlan_tdls_mgmt.h" + +static +const char *const tdls_action_frames_type[] = { "TDLS Setup Request", + "TDLS Setup Response", + "TDLS Setup Confirm", + "TDLS Teardown", + "TDLS Peer Traffic Indication", + "TDLS Channel Switch Request", + "TDLS Channel Switch Response", + "TDLS Peer PSM Request", + "TDLS Peer PSM Response", + "TDLS Peer Traffic Response", + "TDLS Discovery Request"}; + +/** + * tdls_set_rssi() - Set TDLS RSSI on peer given by mac + * @tdls_vdev: tdls vdev object + * @mac: MAC address of Peer + * @rx_rssi: rssi value + * + * Set RSSI on TDSL peer + * + * Return: 0 for success or -EINVAL otherwise + */ +static int tdls_set_rssi(struct tdls_vdev_priv_obj *tdls_vdev, + const uint8_t *mac, + int8_t rx_rssi) +{ + struct tdls_peer *curr_peer; + + curr_peer = tdls_find_peer(tdls_vdev, mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->rssi = rx_rssi; + + return 0; +} + +/** + * tdls_process_rx_mgmt() - process tdls rx mgmt frames + * @rx_mgmt_event: tdls rx mgmt event + * @tdls_vdev: tdls vdev object + * + * Return: QDF_STATUS + */ +static QDF_STATUS tdls_process_rx_mgmt( + struct tdls_rx_mgmt_event *rx_mgmt_event, + struct tdls_vdev_priv_obj *tdls_vdev) +{ + struct tdls_rx_mgmt_frame *rx_mgmt; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint8_t *mac; + enum tdls_actioncode action_frame_type; + + if (!rx_mgmt_event) + return QDF_STATUS_E_INVAL; + + tdls_soc_obj = rx_mgmt_event->tdls_soc_obj; + rx_mgmt = rx_mgmt_event->rx_mgmt; + + if (!tdls_soc_obj || !rx_mgmt) { + tdls_err("invalid psoc object or rx mgmt"); + return QDF_STATUS_E_INVAL; + } + + tdls_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + tdls_soc_obj->soc, rx_mgmt->frame_len, + rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, + rx_mgmt->rx_rssi, rx_mgmt->buf); + + if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1] == + TDLS_PUBLIC_ACTION_DISC_RESP) { + mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET]; + tdls_notice("[TDLS] TDLS Discovery Response," + QDF_MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi); + tdls_recv_discovery_resp(tdls_vdev, mac); + tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); + } + + + if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] == + TDLS_ACTION_FRAME) { + action_frame_type = + rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET + 1]; + if (action_frame_type >= TDLS_ACTION_FRAME_TYPE_MAX) { + tdls_debug("[TDLS] unknown[%d] <--- OTA", + action_frame_type); + } else { + tdls_notice("[TDLS] %s <--- OTA", + tdls_action_frames_type[action_frame_type]); + } + } + + /* tdls_soc_obj->tdls_rx_cb ==> wlan_tdls_rx_callback() */ + if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb) + tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data, + rx_mgmt); + else + tdls_debug("rx mgmt, but no valid up layer callback"); + + qdf_mem_free(rx_mgmt); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_rx_mgmt_event *tdls_rx; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (!(msg->bodyptr)) { + tdls_err("invalid message body"); + return QDF_STATUS_E_INVAL; + } + + tdls_rx = (struct tdls_rx_mgmt_event *) msg->bodyptr; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(tdls_rx->tdls_soc_obj->soc, + tdls_rx->rx_mgmt->vdev_id, WLAN_TDLS_NB_ID); + + if (vdev) { + tdls_debug("tdls rx mgmt frame received"); + + tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev, + WLAN_UMAC_COMP_TDLS); + if (tdls_vdev) + status = tdls_process_rx_mgmt(tdls_rx, tdls_vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + qdf_mem_free(msg->bodyptr); + msg->bodyptr = NULL; + + return status; +} + +QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool isregister) +{ + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; + QDF_STATUS status; + int num_of_entries; + + tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); + + frm_cb_info[0].frm_type = MGMT_PROBE_REQ; + frm_cb_info[0].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + frm_cb_info[1].frm_type = MGMT_ACTION_TDLS_DISCRESP; + frm_cb_info[1].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + frm_cb_info[2].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; + frm_cb_info[2].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + num_of_entries = 3; + + if (isregister) + status = wlan_mgmt_txrx_register_rx_cb(psoc, + WLAN_UMAC_COMP_TDLS, frm_cb_info, + num_of_entries); + else + status = wlan_mgmt_txrx_deregister_rx_cb(psoc, + WLAN_UMAC_COMP_TDLS, frm_cb_info, + num_of_entries); + + return status; +} + +static QDF_STATUS +tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, + QDF_STATUS status) +{ + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!req || !req->vdev) + return QDF_STATUS_E_NULL_VALUE; + + indication.status = status; + indication.vdev = req->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &indication); + return QDF_STATUS_SUCCESS; +} + +static QDF_STATUS tdls_activate_send_mgmt_request( + struct tdls_action_frame_request *action_req) +{ + struct wlan_objmgr_peer *peer; + struct tdls_soc_priv_obj *tdls_soc_obj; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + struct scheduler_msg msg; + struct tdls_send_mgmt_request *tdls_mgmt_req; + + if (!action_req || !action_req->vdev) + return QDF_STATUS_E_NULL_VALUE; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev, + WLAN_TDLS_SB_ID)) + return QDF_STATUS_E_NULL_VALUE; + + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev); + if (!tdls_soc_obj) { + status = QDF_STATUS_E_NULL_VALUE; + goto release_mgmt_ref; + } + + tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) + + action_req->tdls_mgmt.len); + if (NULL == tdls_mgmt_req) { + status = QDF_STATUS_E_NOMEM; + tdls_err("mem alloc failed "); + QDF_ASSERT(0); + goto release_mgmt_ref; + } + + tdls_debug("session_id %d " + "tdls_mgmt.dialog %d " + "tdls_mgmt.frame_type %d " + "tdls_mgmt.status_code %d " + "tdls_mgmt.responder %d " + "tdls_mgmt.peer_capability %d", + action_req->session_id, + action_req->tdls_mgmt.dialog, + action_req->tdls_mgmt.frame_type, + action_req->tdls_mgmt.status_code, + action_req->tdls_mgmt.responder, + action_req->tdls_mgmt.peer_capability); + + tdls_mgmt_req->session_id = action_req->session_id; + /* Using dialog as transactionId. This can be used to + * match response with request + */ + tdls_mgmt_req->transaction_id = action_req->tdls_mgmt.dialog; + tdls_mgmt_req->req_type = action_req->tdls_mgmt.frame_type; + tdls_mgmt_req->dialog = action_req->tdls_mgmt.dialog; + tdls_mgmt_req->status_code = action_req->tdls_mgmt.status_code; + tdls_mgmt_req->responder = action_req->tdls_mgmt.responder; + tdls_mgmt_req->peer_capability = action_req->tdls_mgmt.peer_capability; + + peer = wlan_vdev_get_bsspeer(action_req->vdev); + + if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, + WLAN_TDLS_SB_ID)) { + qdf_mem_free(tdls_mgmt_req); + goto release_mgmt_ref; + } + + qdf_mem_copy(tdls_mgmt_req->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + + qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes, + action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE); + + if (action_req->tdls_mgmt.len && action_req->tdls_mgmt.buf) { + qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf, + action_req->tdls_mgmt.len); + } + + tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) + + action_req->tdls_mgmt.len; + + /* Send the request to PE. */ + qdf_mem_zero(&msg, sizeof(msg)); + + tdls_debug("sending TDLS Mgmt Frame req to PE "); + tdls_mgmt_req->message_type = tdls_soc_obj->tdls_send_mgmt_req; + + msg.type = tdls_soc_obj->tdls_send_mgmt_req; + msg.bodyptr = tdls_mgmt_req; + + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); +release_mgmt_ref: + wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID); + + /*update tdls nss infornation based on action code */ + tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); + + return status; +} + +static QDF_STATUS +tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, + enum wlan_serialization_cb_reason reason) +{ + struct tdls_action_frame_request *req; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!cmd || !cmd->umac_cmd) { + tdls_err("invalid params cmd: %p, ", cmd); + return QDF_STATUS_E_NULL_VALUE; + } + req = cmd->umac_cmd; + + tdls_debug("reason: %d, vdev_id: %d", + reason, req->vdev_id); + + switch (reason) { + case WLAN_SER_CB_ACTIVATE_CMD: + /* command moved to active list */ + status = tdls_activate_send_mgmt_request(req); + break; + + case WLAN_SER_CB_CANCEL_CMD: + case WLAN_SER_CB_ACTIVE_CMD_TIMEOUT: + /* command removed from pending list. + * notify status complete with failure + */ + status = tdls_internal_send_mgmt_tx_done(req, + QDF_STATUS_E_FAILURE); + qdf_mem_free(req); + break; + + case WLAN_SER_CB_RELEASE_MEM_CMD: + /* command successfully completed. + * release tdls_action_frame_request memory + */ + qdf_mem_free(req); + break; + + default: + /* Do nothing but logging */ + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + + return status; +} + +QDF_STATUS tdls_process_mgmt_req( + struct tdls_action_frame_request *tdls_mgmt_req) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_serialization_command cmd = {0, }; + enum wlan_serialization_status ser_cmd_status; + + /* If connected and in Infra. Only then allow this */ + status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame); + if (status != QDF_STATUS_SUCCESS) { + status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, + status); + qdf_mem_free(tdls_mgmt_req); + return status; + } + + /* update the responder, status code information + * after the cmd validation + */ + tdls_mgmt_req->tdls_mgmt.responder = + tdls_mgmt_req->chk_frame->responder; + tdls_mgmt_req->tdls_mgmt.status_code = + tdls_mgmt_req->chk_frame->status_code; + + cmd.cmd_type = WLAN_SER_CMD_TDLS_SEND_MGMT; + /* Cmd Id not applicable for non scan cmds */ + cmd.cmd_id = 0; + cmd.cmd_cb = (wlan_serialization_cmd_callback) + tdls_send_mgmt_serialize_callback; + cmd.umac_cmd = tdls_mgmt_req; + cmd.source = WLAN_UMAC_COMP_TDLS; + cmd.is_high_priority = false; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; + + cmd.vdev = tdls_mgmt_req->vdev; + + ser_cmd_status = wlan_serialization_request(&cmd); + tdls_debug("wlan_serialization_request status:%d", ser_cmd_status); + + switch (ser_cmd_status) { + case WLAN_SER_CMD_PENDING: + /* command moved to pending list.Do nothing */ + break; + case WLAN_SER_CMD_ACTIVE: + /* command moved to active list. Do nothing */ + break; + case WLAN_SER_CMD_DENIED_LIST_FULL: + case WLAN_SER_CMD_DENIED_RULES_FAILED: + case WLAN_SER_CMD_DENIED_UNSPECIFIED: + /* free the request */ + qdf_mem_free(tdls_mgmt_req); + + default: + QDF_ASSERT(0); + status = QDF_STATUS_E_INVAL; + break; + } + return status; +} diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 1abd248412..94e6d11f97 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -21,3 +21,54 @@ * * TDLS management frames include file */ + +#ifndef _WLAN_TDLS_MGMT_H_ +#define _WLAN_TDLS_MGMT_H_ + +/* default tdls serialize timeout is set to 10 secs */ +#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 + +/* + * struct tdls_send_mgmt_request - tdls management request + * @message_type: type of pe message + * @length: length of the frame. + * @session_id: session id + * @transaction_id: transaction ID for cmd + * @req_type: type of action frame + * @dialog: dialog token used in the frame. + * @status_code: status to be incuded in the frame. + * @responder: tdls request type + * @peer_capability: peer capability information + * @bssid: bssid + * @peer_mac: mac address of the peer + * @add_ie: additional ie's to be included + */ +struct tdls_send_mgmt_request { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + uint8_t req_type; + uint8_t dialog; + uint16_t status_code; + uint8_t responder; + uint32_t peer_capability; + struct qdf_mac_addr bssid; + struct qdf_mac_addr peer_mac; + /* Variable length. Dont add any field after this. */ + uint8_t add_ie[1]; +}; + +/** + * tdls_process_mgmt_req() - send a TDLS mgmt request to serialize module + * @tdls_mgmt_req: tdls management request + * + * TDLS request API, called from cfg80211 to send a TDLS frame in + * serialized manner to PE + * + *Return: QDF_STATUS + */ +QDF_STATUS tdls_process_mgmt_req( + struct tdls_action_frame_request *tdls_mgmt_req); +#endif + diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index bb5274fb52..dc43e792e3 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -824,4 +824,44 @@ struct tdls_event_notify { struct wlan_objmgr_vdev *vdev; struct tdls_event_info event; }; + +/** + * struct tdls_event_notify - tdls event notify + * @peer_mac: peer's mac address + * @frame_type: Type of TDLS mgmt frame to be sent + * @dialog: dialog token used in the frame. + * @status_code: status to be incuded in the frame + * @responder: Tdls request type + * @peer_capability: peer cpabilities + * @len: lenght of additional Ies + * @buf: additional IEs to be included + */ +struct tdls_send_mgmt { + struct qdf_mac_addr peer_mac; + uint8_t frame_type; + uint8_t dialog; + uint16_t status_code; + uint8_t responder; + uint32_t peer_capability; + uint8_t len; + /* Variable length, do not add anything after this */ + uint8_t *buf; +}; + +/** + * struct tdls_send_action_frame_request - tdls send mgmt request + * @vdev: vdev object + * @session_id: session id + * @vdev_id: vdev id + * @tdls_mgmt: tdls managment + */ +struct tdls_action_frame_request { + struct wlan_objmgr_vdev *vdev; + uint8_t session_id; + uint8_t vdev_id; + const uint8_t *cmd_buf; + uint8_t len; + struct tdls_send_mgmt tdls_mgmt; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 70a6c450a2..302043fff7 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -118,4 +118,16 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, */ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *macaddr, enum tdls_command_type cmd); + +/** + * ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame + * @mgmt_req: pointer to TDLS action frame request struct + * + * This will TDLS action frames to peer + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_send_mgmt_frame( + struct tdls_action_frame_request *mgmt_req); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7a557a3df2..c57008a19f 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -436,3 +436,42 @@ error: qdf_mem_free(req); return status; } + +QDF_STATUS ucfg_tdls_send_mgmt_frame( + struct tdls_action_frame_request *req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_action_frame_request *mgmt_req; + + if (!req || !req->vdev) { + tdls_err("Invalid mgmt req params %p", req); + return QDF_STATUS_E_NULL_VALUE; + } + + mgmt_req = qdf_mem_malloc(sizeof(*mgmt_req) + + req->len); + if (!mgmt_req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + qdf_mem_copy(mgmt_req, req, sizeof(*req)); + + /*populate the additional IE's */ + if ((0 != req->len) && (NULL != req->cmd_buf)) { + qdf_mem_copy(mgmt_req->tdls_mgmt.buf, req->cmd_buf, + req->len); + mgmt_req->tdls_mgmt.len = req->len; + } else { + mgmt_req->tdls_mgmt.len = 0; + } + + tdls_notice("vdev id: %d, session id : %d", mgmt_req->vdev_id, + mgmt_req->session_id); + msg.bodyptr = mgmt_req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_TX_ACTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return QDF_STATUS_SUCCESS; +} From 03429f458bae6df8a6553365024986c70a9259dc Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 28 Feb 2017 20:28:54 -0800 Subject: [PATCH 10/89] qcacmn: Add sta connect/disconnect in TDLS UMAC component Add sta connection and disconnection event related methods into TDLS component Change-Id: I1309792cf68df87b1ecf5a7686ac645ac21d1c7c CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 666 ++++++++++++++++++++++ core/src/wlan_tdls_main.h | 125 +++- dispatcher/inc/wlan_tdls_public_structs.h | 16 + dispatcher/src/wlan_tdls_ucfg_api.c | 13 +- 4 files changed, 817 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b4b28c0b83..6faeb5dd92 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -27,6 +27,10 @@ #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" #include "wlan_tdls_mgmt.h" +#include "wlan_tdls_tgt_api.h" +#include "wlan_policy_mgr_public_struct.h" +#include "wlan_policy_mgr_api.h" + QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -387,3 +391,665 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } + +/** + * tdls_state_param_setting_dump() - print tdls state & parameters to send to fw + * @info: tdls setting to be sent to fw + * + * Return: void + */ +static void tdls_state_param_setting_dump(struct tdls_info *info) +{ + if (!info) + return; + + tdls_debug("Setting tdls state and param in fw: vdev_id: %d, tdls_state: %d, notification_interval_ms: %d, tx_discovery_threshold: %d, tx_teardown_threshold: %d, rssi_teardown_threshold: %d, rssi_delta: %d, tdls_options: 0x%x, peer_traffic_ind_window: %d, peer_traffic_response_timeout: %d, puapsd_mask: 0x%x, puapsd_inactivity_time: %d, puapsd_rx_frame_threshold: %d, teardown_notification_ms: %d, tdls_peer_kickout_threshold: %d", + info->vdev_id, + info->tdls_state, + info->notification_interval_ms, + info->tx_discovery_threshold, + info->tx_teardown_threshold, + info->rssi_teardown_threshold, + info->rssi_delta, + info->tdls_options, + info->peer_traffic_ind_window, + info->peer_traffic_response_timeout, + info->puapsd_mask, + info->puapsd_inactivity_time, + info->puapsd_rx_frame_threshold, + info->teardown_notification_ms, + info->tdls_peer_kickout_threshold); + +} + +/** + * tdls_update_fw_tdls_state() - update tdls status info + * @tdls_soc_obj: TDLS soc object + * @tdls_info_to_fw: TDLS state info to update in f/w. + * + * send message to WMA to set TDLS state in f/w + * + * Return: QDF_STATUS. + */ +static +QDF_STATUS tdls_update_fw_tdls_state(struct tdls_soc_priv_obj *tdls_soc_obj, + struct tdls_info *tdls_info_to_fw) +{ + QDF_STATUS status; + + /* wmi_unified_update_fw_tdls_state_cmd() will be called directly */ + status = tgt_tdls_set_fw_state(tdls_soc_obj->soc, tdls_info_to_fw); + + if (!QDF_IS_STATUS_SUCCESS(status)) + status = QDF_STATUS_E_FAILURE; + + return status; +} + +bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + bool state = false; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return state; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, + &tdls_soc_obj)) { + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return state; + } + + if (policy_mgr_get_connection_count(tdls_soc_obj->soc) == 1) + state = true; + else + tdls_warn("Concurrent sessions are running or TDLS disabled"); + /* If any concurrency is detected */ + /* print session information */ + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return state; +} + +/** + * cds_set_tdls_ct_mode() - Set the tdls connection tracker mode + * @hdd_ctx: hdd context + * + * This routine is called to set the tdls connection tracker operation status + * + * Return: NONE + */ +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc) +{ + bool state = false; + struct tdls_soc_priv_obj *tdls_soc_obj; + + tdls_soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (NULL == tdls_soc_obj) + return; + + /* If any concurrency is detected, skip tdls pkt tracker */ + if (policy_mgr_get_connection_count(psoc) > 1) { + state = false; + goto set_state; + } + + if (TDLS_SUPPORT_DISABLED == tdls_soc_obj->tdls_current_mode || + TDLS_SUPPORT_SUSPENDED == tdls_soc_obj->tdls_current_mode || + !TDLS_IS_IMPLICIT_TRIG_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags)) { + state = false; + goto set_state; + } else if (policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) == 1) { + state = true; + } else if (policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL) == 1){ + state = true; + } else { + state = false; + goto set_state; + } + + /* In case of TDLS external control, peer should be added + * by the user space to start connection tracker. + */ + if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_soc_obj->tdls_configs.tdls_feature_flags)) { + if (tdls_soc_obj->tdls_external_peer_count) + state = true; + else + state = false; + } + +set_state: + tdls_soc_obj->enable_tdls_connection_tracker = state; + + tdls_notice("enable_tdls_connection_tracker %d", + tdls_soc_obj->enable_tdls_connection_tracker); +} + +QDF_STATUS +tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) +{ + if (!psoc) { + tdls_err("psoc: %p", psoc); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("enter "); + tdls_set_ct_mode(psoc); + tdls_debug("exit "); + return QDF_STATUS_SUCCESS; +} + +/** + * tdls_get_vdev() - Get tdls specific vdev object manager + * @psoc: wlan psoc object manager + * @dbg_id: debug id + * + * If TDLS possible, return the corresponding vdev + * to enable TDLS in the system. + * + * Return: vdev manager pointer or NULL. + */ +struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, + wlan_objmgr_ref_dbgid dbg_id) +{ + if (policy_mgr_get_connection_count(psoc) > 1) + return NULL; + if (policy_mgr_mode_specific_connection_count(psoc, + PM_STA_MODE, + NULL) == 1) + return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_STA_MODE, + dbg_id); + if (policy_mgr_mode_specific_connection_count(psoc, + PM_P2P_CLIENT_MODE, + NULL) == 1) + return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, + QDF_P2P_CLIENT_MODE, + dbg_id); + return NULL; +} + +/** + * tdls_process_session_update() - update session count information + * @psoc: soc object + * @notification: TDLS os if notification + * + * update the session information in connection tracker + * + * Return: None + */ +static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, + enum tdls_command_type cmd_type) +{ + struct scheduler_msg msg = {0}; + QDF_STATUS status; + + msg.bodyptr = psoc; + msg.callback = tdls_process_cmd; + msg.type = (uint16_t)cmd_type; + + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) + tdls_alert("message post failed "); +} + +void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc) +{ + tdls_process_session_update(psoc, TDLS_CMD_SESSION_INCREMENT); +} + +void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) +{ + tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); +} + +/** + * tdls_send_update_to_fw - update tdls status info + * @tdls_vdev_obj: tdls vdev private object. + * @tdls_prohibited: indicates whether tdls is prohibited. + * @tdls_chan_swit_prohibited: indicates whether tdls channel switch + * is prohibited. + * @sta_connect_event: indicate sta connect or disconnect event + * @session_id: session id + * + * Normally an AP does not influence TDLS connection between STAs + * associated to it. But AP may set bits for TDLS Prohibited or + * TDLS Channel Switch Prohibited in Extended Capability IE in + * Assoc/Re-assoc response to STA. So after STA is connected to + * an AP, call this function to update TDLS status as per those + * bits set in Ext Cap IE in received Assoc/Re-assoc response + * from AP. + * + * Return: None. + */ +static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id) +{ + struct tdls_info *tdls_info_to_fw; + struct tdls_config_params *threshold_params; + uint32_t tdls_feature_flags; + QDF_STATUS status; + + + /* If TDLS support is disabled then no need to update target */ + if (tdls_soc_obj->tdls_current_mode <= TDLS_SUPPORT_SUSPENDED) { + tdls_err("TDLS not enabled or suspended"); + return; + } + + if (tdls_soc_obj->set_state_info.set_state_cnt == 0 && + !sta_connect_event) { + return; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + + /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ + if (tdls_prohibited) { + tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; + } else { + tdls_debug("TDLS feature flags from ini %d ", + tdls_feature_flags); + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXT_CONTROL; + else + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_IMP_MODE; + } + + tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); + + if (!tdls_info_to_fw) { + tdls_err("memory allocation failed for tdlsParams"); + QDF_ASSERT(0); + return; + } + + threshold_params = &tdls_vdev_obj->threshold_config; + + tdls_info_to_fw->notification_interval_ms = + threshold_params->tx_period_t; + tdls_info_to_fw->tx_discovery_threshold = + threshold_params->tx_packet_n; + tdls_info_to_fw->tx_teardown_threshold = + threshold_params->idle_packet_n; + tdls_info_to_fw->rssi_teardown_threshold = + threshold_params->rssi_teardown_threshold; + tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta; + + if (tdls_soc_obj->set_state_info.set_state_cnt == 1 && + sta_connect_event) { + tdls_warn("Concurrency not allowed in TDLS! set state cnt %d", + tdls_soc_obj->set_state_info.set_state_cnt); + /* disable off channel and teardown links */ + /* Go through the peer list and delete them */ + tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; + tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id; + } else { + tdls_info_to_fw->vdev_id = session_id; + } + + tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; + tdls_info_to_fw->tdls_options = 0; + + /* Do not enable TDLS offchannel, if AP prohibited TDLS + * channel switch + */ + if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && + (!tdls_chan_swit_prohibited)) + tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN; + + if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags)) + tdls_info_to_fw->tdls_options |= ENA_TDLS_BUFFER_STA; + if (TDLS_IS_SLEEP_STA_ENABLED(tdls_feature_flags)) + tdls_info_to_fw->tdls_options |= ENA_TDLS_SLEEP_STA; + + + tdls_info_to_fw->peer_traffic_ind_window = + tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window; + tdls_info_to_fw->peer_traffic_response_timeout = + tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout; + tdls_info_to_fw->puapsd_mask = + tdls_soc_obj->tdls_configs.tdls_uapsd_mask; + tdls_info_to_fw->puapsd_inactivity_time = + tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time; + tdls_info_to_fw->puapsd_rx_frame_threshold = + tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold; + tdls_info_to_fw->teardown_notification_ms = + tdls_soc_obj->tdls_configs.tdls_idle_timeout; + tdls_info_to_fw->tdls_peer_kickout_threshold = + tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold; + + tdls_state_param_setting_dump(tdls_info_to_fw); + + status = tdls_update_fw_tdls_state(tdls_soc_obj, tdls_info_to_fw); + if (QDF_STATUS_SUCCESS != status) { + qdf_mem_free(tdls_info_to_fw); + goto done; + } + + if (sta_connect_event) { + tdls_soc_obj->set_state_info.set_state_cnt++; + tdls_soc_obj->set_state_info.vdev_id = session_id; + } else { + tdls_soc_obj->set_state_info.set_state_cnt--; + } + + tdls_debug("TDLS Set state cnt %d", + tdls_soc_obj->set_state_info.set_state_cnt); + + if (tdls_soc_obj->set_state_info.set_state_cnt == 1) + /* register callbacks with tx/rx mgmt */ + tdls_mgmt_rx_ops(tdls_soc_obj->soc, true); + else + /* deregister callbacks with tx/rx mgmt */ + tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); + +done: + tdls_process_session_update(tdls_soc_obj->soc, + TDLS_CMD_SESSION_INCREMENT); + return; +} + +static QDF_STATUS +tdls_process_sta_connect(struct tdls_sta_notify_params *notify) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(notify->vdev, + &tdls_vdev_obj, + &tdls_soc_obj)) + return QDF_STATUS_E_INVAL; + + + tdls_debug("Check and update TDLS state"); + + /* Association event */ + if (!tdls_soc_obj->tdls_disable_in_progress) { + tdls_send_update_to_fw(tdls_vdev_obj, + tdls_soc_obj, + notify->tdls_prohibited, + notify->tdls_chan_swit_prohibited, + true, + notify->session_id); + } + + /* check and set the connection tracker */ + tdls_set_ct_mode(tdls_soc_obj->soc); + if (tdls_soc_obj->enable_tdls_connection_tracker) + tdls_implicit_enable(tdls_vdev_obj); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) +{ + QDF_STATUS status; + + if (!notify || !notify->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_process_sta_connect(notify); + + wlan_objmgr_vdev_release_ref(notify->vdev, + WLAN_TDLS_NB_ID); + qdf_mem_free(notify); + return status; +} + +static QDF_STATUS +tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) +{ + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_vdev_priv_obj *curr_tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_soc_priv_obj *curr_tdls_soc; + struct wlan_objmgr_vdev *temp_vdev = NULL; + + + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(notify->vdev, + &tdls_vdev_obj, + &tdls_soc_obj)) + return QDF_STATUS_E_INVAL; + + tdls_debug("Check and update TDLS state"); + + curr_tdls_vdev = tdls_vdev_obj; + curr_tdls_soc = tdls_soc_obj; + + /* Disassociation event */ + if (!tdls_soc_obj->tdls_disable_in_progress) + tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj, false, + false, false, notify->session_id); + + /* If concurrency is not marked, then we have to + * check, whether TDLS could be enabled in the + * system after this disassoc event. + */ + if (!notify->lfr_roam && !tdls_soc_obj->tdls_disable_in_progress) { + temp_vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID); + if (NULL != temp_vdev) { + status = tdls_get_vdev_objects(temp_vdev, + &tdls_vdev_obj, + &tdls_soc_obj); + if (QDF_STATUS_SUCCESS == status) { + tdls_send_update_to_fw(tdls_vdev_obj, + tdls_soc_obj, + false, + false, + true, + notify->session_id); + curr_tdls_vdev = tdls_vdev_obj; + curr_tdls_soc = tdls_soc_obj; + } + } + } + + /* Check and set the connection tracker and implicit timers */ + tdls_set_ct_mode(curr_tdls_soc->soc); + if (curr_tdls_soc->enable_tdls_connection_tracker) + tdls_implicit_enable(curr_tdls_vdev); + else + tdls_implicit_disable(curr_tdls_vdev); + + /* release the vdev ref , if temp vdev was acquired */ + if (temp_vdev) + wlan_objmgr_vdev_release_ref(temp_vdev, + WLAN_TDLS_NB_ID); + + return status; +} + +QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) +{ + QDF_STATUS status; + + if (!notify || !notify->vdev) + return QDF_STATUS_E_INVAL; + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, + WLAN_TDLS_NB_ID)) + return QDF_STATUS_E_INVAL; + + status = tdls_process_sta_disconnect(notify); + + wlan_objmgr_vdev_release_ref(notify->vdev, + WLAN_TDLS_NB_ID); + + qdf_mem_free(notify); + return status; +} + +/** + * tdls_set_mode_in_vdev() - set TDLS mode + * @tdls_vdev: tdls vdev object + * @tdls_soc: tdls soc object + * @tdls_mode: TDLS mode + * @source: TDLS disable source enum values + * + * Return: Void + */ +static void tdls_set_mode_in_vdev(struct tdls_vdev_priv_obj *tdls_vdev, + struct tdls_soc_priv_obj *tdls_soc, + enum tdls_feature_mode tdls_mode, + enum tdls_disable_sources source) +{ + if (!tdls_vdev) + return; + tdls_debug("enter tdls mode is %d", tdls_mode); + + if (TDLS_SUPPORT_IMP_MODE == tdls_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_mode) { + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + /* + * Check if any TDLS source bit is set and if + * bitmap is not zero then we should not + * enable TDLS + */ + if (tdls_soc->tdls_source_bitmap) { + tdls_notice("Don't enable TDLS, source bitmap: %lu", + tdls_soc->tdls_source_bitmap); + return; + } + tdls_implicit_enable(tdls_vdev); + /* tdls implicit mode is enabled, so + * enable the connection tracker + */ + tdls_soc->enable_tdls_connection_tracker = + true; + } else if (TDLS_SUPPORT_DISABLED == tdls_mode) { + set_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_implicit_disable(tdls_vdev); + /* If tdls implicit mode is disabled, then + * stop the connection tracker. + */ + tdls_soc->enable_tdls_connection_tracker = + false; + } else if (TDLS_SUPPORT_EXP_TRIG_ONLY == + tdls_mode) { + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_implicit_disable(tdls_vdev); + /* If tdls implicit mode is disabled, then + * stop the connection tracker. + */ + tdls_soc->enable_tdls_connection_tracker = + false; + + /* + * Check if any TDLS source bit is set and if + * bitmap is not zero then we should not + * enable TDLS + */ + if (tdls_soc->tdls_source_bitmap) + return; + } + tdls_debug("exit "); + +} + +/** + * tdls_set_current_mode() - set TDLS mode + * @tdls_soc: tdls soc object + * @tdls_mode: TDLS mode + * @update_last: indicate to record the last tdls mode + * @source: TDLS disable source enum values + * + * Return: Void + */ +static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, + enum tdls_feature_mode tdls_mode, + bool update_last, + enum tdls_disable_sources source) +{ + struct wlan_objmgr_vdev *vdev; + struct tdls_vdev_priv_obj *tdls_vdev; + + if (!tdls_soc) + return; + + tdls_debug("mode %d", (int)tdls_mode); + + if (update_last) + tdls_soc->tdls_last_mode = tdls_mode; + + if (tdls_soc->tdls_current_mode == tdls_mode) { + tdls_debug("already in mode %d", tdls_mode); + + switch (tdls_mode) { + /* TDLS is already enabled hence clear source mask, return */ + case TDLS_SUPPORT_IMP_MODE: + case TDLS_SUPPORT_EXP_TRIG_ONLY: + case TDLS_SUPPORT_EXT_CONTROL: + clear_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_debug("clear source mask:%d", source); + return; + /* TDLS is already disabled hence set source mask, return */ + case TDLS_SUPPORT_DISABLED: + set_bit((unsigned long)source, + &tdls_soc->tdls_source_bitmap); + tdls_debug("set source mask:%d", source); + return; + default: + return; + } + } + + /* get sta vdev */ + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, + QDF_STA_MODE, + WLAN_TDLS_NB_ID); + if (NULL != vdev) { + tdls_debug("set mode in tdls vdev "); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, + tdls_mode, source); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + /* get p2p client vdev */ + vdev = wlan_objmgr_get_vdev_by_opmode_from_psoc(tdls_soc->soc, + QDF_P2P_CLIENT_MODE, + WLAN_TDLS_NB_ID); + if (NULL != vdev) { + tdls_debug("set mode in tdls vdev "); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + tdls_set_mode_in_vdev(tdls_vdev, tdls_soc, + tdls_mode, source); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + + if (!update_last) + tdls_soc->tdls_last_mode = tdls_soc->tdls_current_mode; + + tdls_soc->tdls_current_mode = tdls_mode; + +} diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index cf758e772e..e6929facff 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -145,7 +145,8 @@ struct tdls_set_state_info { * struct tdls_psoc_priv_ctx - tdls context * @soc: objmgr psoc * @tdls_current_mode: current tdls mode - * @tdls_user_config_mode: user configure tdls mode + * @tdls_last_mode: last tdls mode + * @tdls_source_bitmap: bit map to set/reset TDLS by different sources * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type * of peer object to get the active tdls peers * @tdls_configs: tdls user configure @@ -180,7 +181,8 @@ struct tdls_set_state_info { struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; enum tdls_feature_mode tdls_current_mode; - enum tdls_feature_mode tdls_user_config_mode; + enum tdls_feature_mode tdls_last_mode; + unsigned long tdls_source_bitmap; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; uint16_t max_num_tdls_sta; @@ -192,6 +194,7 @@ struct tdls_soc_priv_obj { uint8_t tdls_external_peer_count; bool tdls_nss_switch_in_progress; bool tdls_nss_teardown_complete; + bool tdls_disable_in_progress; enum tdls_nss_transition_state tdls_nss_transition_mode; int32_t tdls_teardown_peers_cnt; struct tdls_set_state_info set_state_info; @@ -320,6 +323,25 @@ struct tdls_peer { struct tdls_peer_mlme_info *tdls_info; }; +/** + * struct tdls_os_if_event - TDLS os event info + * @type: type of event + * @info: pointer to event information + */ +struct tdls_os_if_event { + uint32_t type; + void *info; +}; + +/** + * enum tdls_os_if_notification - TDLS notification from OS IF + * @TDLS_NOTIFY_STA_SESSION_INCREMENT: sta session count incremented + * @TDLS_NOTIFY_STA_SESSION_DECREMENT: sta session count decremented + */ +enum tdls_os_if_notification { + TDLS_NOTIFY_STA_SESSION_INCREMENT, + TDLS_NOTIFY_STA_SESSION_DECREMENT +}; /** * wlan_vdev_get_tdls_soc_obj - private API to get tdls soc object from vdev * @vdev: vdev object @@ -501,4 +523,103 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, struct tdls_vdev_priv_obj **tdls_vdev_obj, struct tdls_soc_priv_obj **tdls_soc_obj); +/** + * cds_set_tdls_ct_mode() - Set the tdls connection tracker mode + * @hdd_ctx: hdd context + * + * This routine is called to set the tdls connection tracker operation status + * + * Return: NONE + */ +void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_notify_sta_connect() - Update tdls state for every + * connect event. + * @vdev: vdev object manager + * @tdls_prohibited: flag to tell whether tdls prohibited in this bss + * @tdls_chan_swit_prohibited: flag to tell whether tdls channel switch + * prohibited in this bss + * @session_id: session id + * + * After every connect event in the system, check whether TDLS + * can be enabled in the system. If TDLS can be enabled, update the + * TDLS state as needed. + * + * Return: None + */ +void tdls_notify_sta_connect(struct wlan_objmgr_vdev *vdev, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + uint8_t session_id); + +/** + * tdls_notify_sta_disconnect() - Update tdls state for every + * disconnect event. + * @vdev: vdev object manager + * @lfr_roam: roaming case + * @session_id: session id + * + * After every disconnect event in the system, check whether TDLS + * can be disabled/enabled in the system and update the + * TDLS state as needed. + * + * Return: None + */ +void tdls_notify_sta_disconnect(struct wlan_objmgr_vdev *vdev, + bool lfr_roam, + uint8_t session_id); + +/** + * tdls_notify_decrement_session() - Notify the session decrement + * @psoc: psoc object manager + * + * Policy manager notify TDLS about session decrement + * + * Return: None + */ +void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_notify_increment_session() - Notify the session increment + * @psoc: psoc object manager + * + * Policy manager notify TDLS about session increment + * + * Return: None + */ +void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc); + +/** + * tdls_check_is_tdls_allowed() - check is tdls allowed or not + * @vdev: vdev object + * + * Function determines the whether TDLS allowed in the system + * + * Return: true or false + */ +bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_get_vdev() - Get tdls specific vdev object manager + * @psoc: wlan psoc object manager + * @dbg_id: debug id + * + * If TDLS possible, return the corresponding vdev + * to enable TDLS in the system. + * + * Return: vdev manager pointer or NULL. + */ +struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, + wlan_objmgr_ref_dbgid dbg_id); + +/** + * tdls_process_policy_mgr_notification() - process policy manager notification + * @psoc: soc object manager + * + * Return: QDF_STATUS + */ +QDF_STATUS +tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc); + #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index dc43e792e3..39e9ddebe7 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -286,6 +286,22 @@ enum tdls_event_reason { TDLS_SCAN_COMPLETED, }; +/** + * enum tdls_disable_sources - TDLS disable sources + * @TDLS_SET_MODE_SOURCE_USER: disable from user + * @TDLS_SET_MODE_SOURCE_SCAN: disable during scan + * @TDLS_SET_MODE_SOURCE_OFFCHANNEL: disable during offchannel + * @TDLS_SET_MODE_SOURCE_BTC: disable during bluetooth + * @TDLS_SET_MODE_SOURCE_P2P: disable during p2p + */ +enum tdls_disable_sources { + TDLS_SET_MODE_SOURCE_USER = 0, + TDLS_SET_MODE_SOURCE_SCAN, + TDLS_SET_MODE_SOURCE_OFFCHANNEL, + TDLS_SET_MODE_SOURCE_BTC, + TDLS_SET_MODE_SOURCE_P2P, +}; + /** * struct tdls_osif_indication - tdls indication to os if layer * @vdev: vdev object diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c57008a19f..be63fbdbd8 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -28,6 +28,7 @@ #include "../../core/src/wlan_tdls_cmds_process.h" #include #include +#include "wlan_policy_mgr_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -122,7 +123,6 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->tdls_teardown_peers_cnt = 0; soc_obj->tdls_nss_teardown_complete = false; soc_obj->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_S_UNKNOWN; - soc_obj->tdls_user_config_mode = TDLS_SUPPORT_DISABLED; feature = soc_obj->tdls_configs.tdls_feature_flags; if (TDLS_IS_BUFFER_STA_ENABLED(feature) || @@ -178,6 +178,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, { struct tdls_soc_priv_obj *soc_obj; uint32_t tdls_feature_flags; + struct policy_mgr_tdls_cbacks tdls_pm_call_backs; tdls_notice("tdls update config "); if (!psoc || !req) { @@ -208,6 +209,16 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + tdls_pm_call_backs.tdls_notify_increment_session = + tdls_notify_increment_session; + + tdls_pm_call_backs.tdls_notify_decrement_session = + tdls_notify_decrement_session; + if (QDF_STATUS_SUCCESS != policy_mgr_register_tdls_cb( + psoc, &tdls_pm_call_backs)) { + tdls_err("policy manager callback registration failed "); + return QDF_STATUS_E_FAILURE; + } /* Update TDLS user config */ qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); From 53f502c2699a34b5b71c84d13e7551da69414562 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Fri, 14 Apr 2017 23:36:42 -0700 Subject: [PATCH 11/89] qcacmn: Add TDLS ucfg changes for sta connect/disconnect Add TDLS ucfg interface changes for sta connect, sta disconnect and tx/rx data sample Change-Id: Ic57a91b70fe462ee031dc0cf54112601aae0dfc4 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 57 ++++++++ core/src/wlan_tdls_cmds_process.h | 8 ++ core/src/wlan_tdls_main.c | 49 +++++++ core/src/wlan_tdls_main.h | 31 ++--- dispatcher/inc/wlan_tdls_public_structs.h | 137 ++++++++++++++++++-- dispatcher/inc/wlan_tdls_ucfg_api.h | 55 ++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 150 ++++++++++++++++++++++ 7 files changed, 461 insertions(+), 26 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 49784df9bd..51361b65c1 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1759,3 +1759,60 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, /*TODO connection tracker update*/ return QDF_STATUS_SUCCESS; } + +/** + * tdls_process_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +static +int tdls_process_set_responder(struct tdls_set_responder_req *set_req) +{ + struct tdls_peer *curr_peer; + struct tdls_vdev_priv_obj *tdls_vdev; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(set_req->vdev); + if (!tdls_vdev) { + tdls_err("tdls vdev obj is NULL"); + return -EINVAL; + } + curr_peer = tdls_get_peer(tdls_vdev, set_req->peer_mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->is_responder = set_req->responder; + return 0; +} + + +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req) +{ + QDF_STATUS status; + + if (!set_req || !set_req->vdev) { + tdls_err("Invalid input params %p", set_req); + return -EINVAL; + } + + status = wlan_objmgr_vdev_try_get_ref(set_req->vdev, WLAN_TDLS_NB_ID); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("vdev object is deleted"); + return -EINVAL; + } + + status = tdls_process_set_responder(set_req); + + wlan_objmgr_vdev_release_ref(set_req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(set_req); + return status; +} + diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 32e8cba01a..8c17dfebd4 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -259,4 +259,12 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, */ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); +/** + * tdls_set_responder() - Set/clear TDLS peer's responder role + * @set_req: set responder request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_set_responder(struct tdls_set_responder_req *set_req); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 6faeb5dd92..879290e56b 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -241,6 +241,23 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_CMD_CONFIG_UPDATE: break; + case TDLS_CMD_SET_RESPONDER: + tdls_set_responder(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_CONNECTION: + tdls_notify_sta_connect(msg->bodyptr); + break; + case TDLS_NOTIFY_STA_DISCONNECTION: + tdls_notify_sta_disconnect(msg->bodyptr); + break; + case TDLS_CMD_SET_TDLS_MODE: + tdls_set_operation_mode(msg->bodyptr); + break; + case TDLS_CMD_SESSION_INCREMENT: + case TDLS_CMD_SESSION_DECREMENT: + tdls_process_policy_mgr_notification(msg->bodyptr); + break; + default: break; } @@ -1053,3 +1070,35 @@ static void tdls_set_current_mode(struct tdls_soc_priv_obj *tdls_soc, tdls_soc->tdls_current_mode = tdls_mode; } + +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode) +{ + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + 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) + goto release_mode_ref; + + tdls_set_current_mode(tdls_soc, + tdls_set_mode->tdls_mode, + tdls_set_mode->update_last, + tdls_set_mode->source); + +release_mode_ref: + wlan_objmgr_vdev_release_ref(tdls_set_mode->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(tdls_set_mode); + return status; +} + diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index e6929facff..769f2533c5 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -533,42 +533,39 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, */ void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc); +/** + * tdls_set_operation_mode() - set tdls operating mode + * @tdls_set_mode: tdls mode set params + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode); + /** * tdls_notify_sta_connect() - Update tdls state for every * connect event. - * @vdev: vdev object manager - * @tdls_prohibited: flag to tell whether tdls prohibited in this bss - * @tdls_chan_swit_prohibited: flag to tell whether tdls channel switch - * prohibited in this bss - * @session_id: session id + * @notify: sta connect params * * After every connect event in the system, check whether TDLS * can be enabled in the system. If TDLS can be enabled, update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_connect(struct wlan_objmgr_vdev *vdev, - bool tdls_prohibited, - bool tdls_chan_swit_prohibited, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); /** * tdls_notify_sta_disconnect() - Update tdls state for every * disconnect event. - * @vdev: vdev object manager - * @lfr_roam: roaming case - * @session_id: session id + * @notify: sta disconnect params * * After every disconnect event in the system, check whether TDLS * can be disabled/enabled in the system and update the * TDLS state as needed. * - * Return: None + * Return: QDF_STATUS */ -void tdls_notify_sta_disconnect(struct wlan_objmgr_vdev *vdev, - bool lfr_roam, - uint8_t session_id); +QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); /** * tdls_notify_decrement_session() - Notify the session decrement diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 39e9ddebe7..4d4b7be416 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -178,7 +178,14 @@ enum tdls_command_type { TDLS_CMD_CONFIG_FORCE_PEER, TDLS_CMD_REMOVE_FORCE_PEER, TDLS_CMD_STATS_UPDATE, - TDLS_CMD_CONFIG_UPDATE + TDLS_CMD_CONFIG_UPDATE, + TDLS_CMD_SCAN_DONE, + TDLS_CMD_SET_RESPONDER, + TDLS_NOTIFY_STA_CONNECTION, + TDLS_NOTIFY_STA_DISCONNECTION, + TDLS_CMD_SET_TDLS_MODE, + TDLS_CMD_SESSION_INCREMENT, + TDLS_CMD_SESSION_DECREMENT, }; /** @@ -350,21 +357,21 @@ enum tdls_feature_bit { }; #define TDLS_IS_OFF_CHANNEL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_OFF_CHANNEL, flags) + CHECK_BIT(flags, TDLS_FEATURE_OFF_CHANNEL) #define TDLS_IS_WMM_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_WMM, flags) + CHECK_BIT(flags, TDLS_FEATURE_WMM) #define TDLS_IS_BUFFER_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_BUFFER_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_BUFFER_STA) #define TDLS_IS_SLEEP_STA_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SLEEP_STA, flags) + CHECK_BIT(flags, TDLS_FEATURE_SLEEP_STA) #define TDLS_IS_SCAN_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_SCAN, flags) + CHECK_BIT(flags, TDLS_FEATURE_SCAN) #define TDLS_IS_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_ENABLE, flags) + CHECK_BIT(flags, TDLS_FEATURE_ENABLE) #define TDLS_IS_IMPLICIT_TRIG_ENABLED(flags) \ - CHECK_BIT(TDLS_FEAUTRE_IMPLICIT_TRIGGER, flags) + CHECK_BIT(flags, TDLS_FEAUTRE_IMPLICIT_TRIGGER) #define TDLS_IS_EXTERNAL_CONTROL_ENABLED(flags) \ - CHECK_BIT(TDLS_FEATURE_EXTERNAL_CONTROL, flags) + CHECK_BIT(flags, TDLS_FEATURE_EXTERNAL_CONTROL) /** * struct tdls_user_config - TDLS user configuration @@ -448,6 +455,47 @@ struct tdls_tx_cnf { int status; }; +/** + * struct tdls_rx_mgmt_frame - rx mgmt frame structure + * @frame_len: frame length + * @rx_chan: rx channel + * @vdev_id: vdev id + * @frm_type: frame type + * @rx_rssi: rx rssi + * @buf: buffer address + */ +struct tdls_rx_mgmt_frame { + uint32_t frame_len; + uint32_t rx_chan; + uint32_t vdev_id; + uint32_t frm_type; + uint32_t rx_rssi; + uint8_t buf[1]; +}; + +/** + * tdls_rx_callback() - Callback for rx mgmt frame + * @user_data: user data associated to this rx mgmt frame. + * @rx_frame: RX mgmt frame + * + * This callback will be used to give rx frames to hdd. + * + * Return: None + */ +typedef void (*tdls_rx_callback)(void *user_data, + struct tdls_rx_mgmt_frame *rx_frame); + +/** + * tdls_wmm_check() - Callback for wmm info + * @psoc: psoc object + * + * This callback will be used to check wmm information + * + * Return: true or false + */ +typedef bool (*tdls_wmm_check)(struct wlan_objmgr_vdev **vdev); + + /* This callback is used to report state change of peer to wpa_supplicant */ typedef int (*tdls_state_change_callback)(const uint8_t *mac, uint32_t opclass, @@ -497,6 +545,10 @@ struct tdls_start_params { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + tdls_rx_callback tdls_rx_cb; + void *tdls_rx_cb_data; + tdls_wmm_check tdls_wmm_cb; + void *tdls_wmm_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; @@ -848,6 +900,7 @@ struct tdls_event_notify { * @dialog: dialog token used in the frame. * @status_code: status to be incuded in the frame * @responder: Tdls request type + * @len: lenght of additional Ies * @peer_capability: peer cpabilities * @len: lenght of additional Ies * @buf: additional IEs to be included @@ -864,15 +917,39 @@ struct tdls_send_mgmt { uint8_t *buf; }; +/** + * struct tdls_validate_action_req - tdls validate mgmt request + * @vdev: vdev object + * @action_code: action code + * @peer_mac: peer mac address + * @dialog_token: dialog code + * @status_code: status code to add + * @len: len of the frame + * @responder: whether to respond or not + * @max_sta_failed: mgmt failure reason + */ +struct tdls_validate_action_req { + struct wlan_objmgr_vdev *vdev; + uint8_t action_code; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t dialog_token; + uint8_t status_code; + size_t len; + int responder; + int max_sta_failed; +}; + /** * struct tdls_send_action_frame_request - tdls send mgmt request * @vdev: vdev object + * @chk_frame: frame validation structure * @session_id: session id * @vdev_id: vdev id * @tdls_mgmt: tdls managment */ struct tdls_action_frame_request { struct wlan_objmgr_vdev *vdev; + struct tdls_validate_action_req *chk_frame; uint8_t session_id; uint8_t vdev_id; const uint8_t *cmd_buf; @@ -880,4 +957,46 @@ struct tdls_action_frame_request { struct tdls_send_mgmt tdls_mgmt; }; +/** + * struct tdls_set_responder_req - tdls set responder in peer + * @vdev: vdev object + * @peer_mac: peer mac address + * @responder: whether to respond or not + */ +struct tdls_set_responder_req { + struct wlan_objmgr_vdev *vdev; + uint8_t peer_mac[QDF_MAC_ADDR_SIZE]; + uint8_t responder; +}; + +/** + * struct tdls_sta_notify_params - STA connection notify info + * @vdev: vdev object + * @tdls_prohibited: peer mac addr + * @tdls_chan_swit_prohibited: peer type + * @lfr_roam: is trigger due to lfr + * @session_id: session id + */ +struct tdls_sta_notify_params { + struct wlan_objmgr_vdev *vdev; + bool tdls_prohibited; + bool tdls_chan_swit_prohibited; + bool lfr_roam; + uint8_t session_id; +}; + +/** + * struct tdls_set_mode_params - TDLS set mode params + * @vdev: vdev object + * @tdls_mode: tdls mode to set + * @update_last: inform to update last tdls mode + * @source: mode change requester + */ +struct tdls_set_mode_params { + struct wlan_objmgr_vdev *vdev; + enum tdls_feature_mode tdls_mode; + bool update_last; + enum tdls_disable_sources source; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 302043fff7..6c7d117b44 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -130,4 +130,59 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *mgmt_req); +/** + * ucfg_tdls_responder() - set responder in TDLS peer + * @msg_req: responder msg + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); + +/** + * ucfg_tdls_notify_sta_connect() - notify sta connect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_notify_sta_disconnect() - notify sta disconnect + * @notify_info: sta notification info + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info); + +/** + * ucfg_tdls_set_operating_mode() - set operating mode + * @set_mode_params: set mode params + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params); + +/** + * ucfg_tdls_update_rx_pkt_cnt() - update rx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + +/** + * ucfg_tdls_update_tx_pkt_cnt() - update tx pkt count + * @vdev: tdls vdev object + * @mac_addr: peer mac address + * + * Return: None + */ +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index be63fbdbd8..ce21c05bf4 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -26,6 +26,7 @@ #include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" +#include "../../core/src/wlan_tdls_ct.h" #include #include #include "wlan_policy_mgr_api.h" @@ -486,3 +487,152 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( return QDF_STATUS_SUCCESS; } + +QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_responder_req *msg_req; + QDF_STATUS status; + + if (!req || !req->vdev) { + tdls_err("invalid input %p", req); + return QDF_STATUS_E_NULL_VALUE; + } + + msg_req = qdf_mem_malloc(sizeof(*msg_req)); + if (!msg_req) + return QDF_STATUS_E_NULL_VALUE; + + msg_req->responder = req->responder; + msg_req->vdev = req->vdev; + qdf_mem_copy(msg_req->peer_mac, req->peer_mac, QDF_MAC_ADDR_SIZE); + + msg.bodyptr = msg_req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_RESPONDER; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return status; +} + +QDF_STATUS ucfg_tdls_notify_sta_connect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = + notify_info->tdls_chan_swit_prohibited; + notify->tdls_prohibited = notify_info->tdls_prohibited; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_CONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_notify_sta_disconnect( + struct tdls_sta_notify_params *notify_info) +{ + struct scheduler_msg msg = {0, }; + struct tdls_sta_notify_params *notify; + + if (!notify_info || !notify_info->vdev) { + tdls_err("notify_info->vdev: %p, notify_info %p", + notify_info->vdev, notify_info); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) + return QDF_STATUS_E_NULL_VALUE; + + notify->session_id = notify_info->session_id; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->vdev = notify_info->vdev; + + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_DISCONNECTION; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS ucfg_tdls_set_operating_mode( + struct tdls_set_mode_params *set_mode_params) +{ + struct scheduler_msg msg = {0, }; + struct tdls_set_mode_params *set_mode; + + if (!set_mode_params || !set_mode_params->vdev) { + tdls_err("vdev: %p, set_mode_params %p", + set_mode_params->vdev, set_mode_params); + return QDF_STATUS_E_NULL_VALUE; + } + + tdls_notice("Enter "); + + set_mode = qdf_mem_malloc(sizeof(*set_mode)); + if (!set_mode) + return QDF_STATUS_E_NULL_VALUE; + + set_mode->source = set_mode_params->source; + set_mode->tdls_mode = set_mode_params->tdls_mode; + set_mode->update_last = set_mode_params->update_last; + set_mode->vdev = set_mode_params->vdev; + + msg.bodyptr = set_mode; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_TDLS_MODE; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + + return QDF_STATUS_SUCCESS; +} + +void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_rx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, + struct qdf_mac_addr *mac_addr) +{ + QDF_STATUS status; + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (status != QDF_STATUS_SUCCESS) + return; + tdls_update_tx_pkt_cnt(vdev, mac_addr); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} From b4c693d7f2b9421dd752ca3ac8f508f66a689fca Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 27 Mar 2017 23:42:04 -0700 Subject: [PATCH 12/89] qcacmn: Add scan related events for TDLS component Add Scan start and complete events for TDLS component Change-Id: Ibb452d2823115ec16a7c6e9f88c9ad6cac48930c CRs-Fixed: 2034220 --- core/src/wlan_tdls_main.c | 165 +++++++++++++++++++++++++++- core/src/wlan_tdls_main.h | 43 ++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 14 ++- 3 files changed, 220 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 879290e56b..5fef8c76e7 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -31,6 +31,11 @@ #include "wlan_policy_mgr_public_struct.h" #include "wlan_policy_mgr_api.h" +/* Global tdls soc pvt object + * this is useful for some functions which does not receive either vdev or psoc + * objects. + */ +static struct tdls_soc_priv_obj *tdls_soc_global; QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg_list) @@ -56,6 +61,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, qdf_mem_free(tdls_soc_obj); } + tdls_soc_global = tdls_soc_obj; tdls_notice("TDLS obj attach to psoc successfully"); return status; @@ -141,6 +147,8 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, { QDF_STATUS status; struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct wlan_objmgr_pdev *pdev; + struct tdls_soc_priv_obj *tdls_soc; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && @@ -169,6 +177,23 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) goto out; + tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc) { + tdls_err("get soc by vdev failed "); + return QDF_STATUS_E_NOMEM; + } + + pdev = wlan_vdev_get_pdev(vdev); + + status = ucfg_scan_register_event_handler(pdev, + tdls_scan_complete_event_handler, + tdls_soc); + + if (QDF_STATUS_SUCCESS != status) { + tdls_err("scan event register failed "); + return QDF_STATUS_E_FAILURE; + } + tdls_notice("tdls object attach to vdev successfully"); out: return status; @@ -244,6 +269,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SET_RESPONDER: tdls_set_responder(msg->bodyptr); break; + case TDLS_CMD_SCAN_DONE: + tdls_scan_done_callback(msg->bodyptr); + break; case TDLS_NOTIFY_STA_CONNECTION: tdls_notify_sta_connect(msg->bodyptr); break; @@ -257,7 +285,6 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SESSION_DECREMENT: tdls_process_policy_mgr_notification(msg->bodyptr); break; - default: break; } @@ -1102,3 +1129,139 @@ release_mode_ref: return status; } +/** + * wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event + * @pAdapter: HDD adapter + * + * Return: Void + */ +void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) +{ + if (!tdls_soc) + return; + + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) { + tdls_notice("TDLS mode is disabled OR not enabled"); + return; + } + + /* if tdls was enabled before scan, re-enable tdls mode */ + if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || + TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) { + tdls_notice("revert tdls mode %d", + tdls_soc->tdls_last_mode); + + tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, + false, + TDLS_SET_MODE_SOURCE_SCAN); + } +} + +/** + * tdls_post_scan_done_msg() - post scan done message to tdls cmd queue + * @tdls_soc: tdls soc object + * + * Return: QDF_STATUS_SUCCESS or QDF_STATUS_E_NULL_VALUE + */ +static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) +{ + struct scheduler_msg msg = {0, }; + + if (!tdls_soc) { + tdls_err("tdls_soc: %p ", tdls_soc); + return QDF_STATUS_E_NULL_VALUE; + } + + msg.bodyptr = tdls_soc; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SCAN_DONE; + scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + return QDF_STATUS_SUCCESS; +} + +void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg) +{ + enum tQDF_ADAPTER_MODE device_mode; + struct tdls_soc_priv_obj *tdls_soc; + + if (!vdev || !event || !arg) + return; + + if (SCAN_EVENT_TYPE_COMPLETED != event->type) + return; + + device_mode = wlan_vdev_mlme_get_opmode(vdev); + + if (device_mode != QDF_STA_MODE && + device_mode != QDF_P2P_CLIENT_MODE) + return; + tdls_soc = (struct tdls_soc_priv_obj *) arg; + tdls_post_scan_done_msg(tdls_soc); +} + +QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) +{ + struct tdls_peer *curr_peer; + struct tdls_vdev_priv_obj *tdls_vdev; + struct wlan_objmgr_vdev *vdev; + QDF_STATUS status = QDF_STATUS_SUCCESS; + + /* if tdls is not enabled, then continue scan */ + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) + return status; + + /* Get the vdev based on vdev operating mode*/ + vdev = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_NB_ID); + if (!vdev) + return status; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + goto return_success; + + curr_peer = tdls_is_progress(tdls_vdev, NULL, 0); + if (NULL != curr_peer) { + if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { + tdls_notice(QDF_MAC_ADDRESS_STR + ". scan rejected %d. force it to idle", + QDF_MAC_ADDR_ARRAY( + curr_peer->peer_mac.bytes), + tdls_soc->scan_reject_count); + tdls_soc->scan_reject_count = 0; + + tdls_set_peer_link_status(curr_peer, + TDLS_LINK_IDLE, + TDLS_LINK_UNSPECIFIED); + status = QDF_STATUS_SUCCESS; + } else { + tdls_warn("tdls in progress. scan rejected %d", + tdls_soc->scan_reject_count); + status = QDF_STATUS_E_BUSY; + } + } +return_success: + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); + return status; +} + +void tdls_scan_serialization_comp_info_cb( + union wlan_serialization_rules_info *comp_info) +{ + struct tdls_soc_priv_obj *tdls_soc; + QDF_STATUS status; + if (!comp_info) + return; + + tdls_soc = tdls_soc_global; + comp_info->scan_info.is_tdls_in_progress = false; + status = tdls_scan_callback(tdls_soc); + if (QDF_STATUS_E_BUSY == status) + comp_info->scan_info.is_tdls_in_progress = true; +} + + diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 769f2533c5..30ace45119 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -33,6 +33,7 @@ #include #include #include +#include "wlan_serialization_api.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ @@ -54,6 +55,8 @@ * should not be more than 2000. */ #define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 +#define TDLS_SCAN_REJECT_MAX 5 + #define tdls_log(level, args...) \ QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) @@ -146,6 +149,7 @@ struct tdls_set_state_info { * @soc: objmgr psoc * @tdls_current_mode: current tdls mode * @tdls_last_mode: last tdls mode + * @scan_reject_count: number of times scan rejected due to TDLS * @tdls_source_bitmap: bit map to set/reset TDLS by different sources * @tdls_conn_info: this tdls_conn_info can be removed and we can use peer type * of peer object to get the active tdls peers @@ -182,6 +186,7 @@ struct tdls_soc_priv_obj { struct wlan_objmgr_psoc *soc; enum tdls_feature_mode tdls_current_mode; enum tdls_feature_mode tdls_last_mode; + int scan_reject_count; unsigned long tdls_source_bitmap; struct tdls_conn_info tdls_conn_info[WLAN_TDLS_STA_MAX_NUM]; struct tdls_user_config tdls_configs; @@ -619,4 +624,42 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc); +/** + * tdls_scan_complete_event_handler() - scan complete event handler for tdls + * @vdev: vdev object + * @event: scan event + * @arg: tdls soc object + * + * Return: None + */ +void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, + struct scan_event *event, + void *arg); + +/** + * tdls_scan_callback() - callback for TDLS scan operation + * @soc: tdls soc pvt object + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc); + +/** + * wlan_hdd_tdls_scan_done_callback() - callback for tdls scan done event + * @tdls_soc: tdls soc object + * + * Return: Void + */ +void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); + +/** + * tdls_scan_serialization_comp_info_cb() - callback for scan start + * @comp_info: serialize rules info + * + * Return: negative = caller should stop and return error code immediately + * 1 = caller can continue to scan + */ +void tdls_scan_serialization_comp_info_cb( + union wlan_serialization_rules_info *comp_info); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index ce21c05bf4..1e4afdbfaa 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -30,6 +30,7 @@ #include #include #include "wlan_policy_mgr_api.h" +#include "wlan_scan_ucfg_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -134,7 +135,6 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) else soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; - for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { soc_obj->tdls_conn_info[sta_idx].sta_id = 0; soc_obj->tdls_conn_info[sta_idx].session_id = 255; @@ -247,6 +247,18 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) status = tgt_tdls_register_ev_handler(psoc); + if (status != QDF_STATUS_SUCCESS) + return status; + + status = wlan_serialization_register_comp_info_cb(psoc, + WLAN_UMAC_COMP_TDLS, + WLAN_SER_CMD_SCAN, + tdls_scan_serialization_comp_info_cb); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("Serialize scan cmd register failed "); + status = QDF_STATUS_E_FAILURE; + } + return status; } From f3f11a78c3cbbc1736cab00c8e2bb5f2e9adc392 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 26 Mar 2017 18:52:47 -0700 Subject: [PATCH 13/89] qcacmn: Add os_if changes for tdls management Add os interface changes to send tdls management frames to tdls component Change-Id: Ib675e4b089a88ad618f918d9992a777c7221b34c CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 349 +++++++++++++++++++++- core/src/wlan_tdls_cmds_process.h | 98 ++++++ core/src/wlan_tdls_ct.c | 21 ++ core/src/wlan_tdls_ct.h | 17 ++ core/src/wlan_tdls_main.c | 2 + core/src/wlan_tdls_main.h | 7 +- core/src/wlan_tdls_mgmt.c | 5 +- core/src/wlan_tdls_mgmt.h | 39 +++ dispatcher/inc/wlan_tdls_public_structs.h | 6 +- dispatcher/inc/wlan_tdls_tgt_api.h | 35 +++ dispatcher/src/wlan_tdls_tgt_api.c | 151 ++++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 15 +- 12 files changed, 736 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 51361b65c1..26594e3f37 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -569,6 +569,244 @@ tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, return status; } +void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, + uint8_t action_code) +{ + if (!tdls_soc) + return; + + if (TDLS_TEARDOWN != action_code || + tdls_soc->tdls_nss_switch_in_progress) + return; + + if (tdls_soc->tdls_teardown_peers_cnt != 0) + tdls_soc->tdls_teardown_peers_cnt--; + if (tdls_soc->tdls_teardown_peers_cnt == 0) { + if (tdls_soc->tdls_nss_transition_mode == + TDLS_NSS_TRANSITION_S_1x1_to_2x2) { + /* TDLS NSS switch is fully completed, so + * reset the flags. + */ + tdls_notice("TDLS NSS switch is fully completed"); + tdls_soc->tdls_nss_switch_in_progress = false; + tdls_soc->tdls_nss_teardown_complete = false; + } else { + /* TDLS NSS switch is not yet completed, but + * tdls teardown is completed for all the + * peers. + */ + tdls_notice("teardown done & NSS switch in progress"); + tdls_soc->tdls_nss_teardown_complete = true; + } + } + +} + +/** + * tdls_set_cap() - set TDLS capability type + * @tdls_vdev: tdls vdev object + * @mac: peer mac address + * @cap: TDLS capability type + * + * Return: 0 if successful or negative errno otherwise + */ +int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, + enum tdls_peer_capab cap) +{ + struct tdls_peer *curr_peer; + + curr_peer = tdls_get_peer(tdls_vdev, mac); + if (curr_peer == NULL) { + tdls_err("curr_peer is NULL"); + return -EINVAL; + } + + curr_peer->tdls_support = cap; + return 0; +} + +static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, + struct tdls_validate_action_req *tdls_validate) +{ + /* supplicant still sends tdls_mgmt(SETUP_REQ) + * even after we return error code at + * 'add_station()'. Hence we have this check + * again in addition to add_station(). Anyway, + * there is no harm to double-check. + */ + if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { + tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, + tdls_soc->connected_peer_count, + tdls_soc->max_num_tdls_sta); + return -EINVAL; + } + /* maximum reached. tweak to send + * error code to peer and return error + * code to supplicant + */ + tdls_validate->status_code = QDF_STATUS_E_RESOURCES; + tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, + tdls_soc->connected_peer_count, + tdls_soc->max_num_tdls_sta); + + tdls_validate->max_sta_failed = -EPERM; + return 0; +} + +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) +{ + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + struct tdls_peer *curr_peer; + struct tdls_peer *temp_peer; + QDF_STATUS status; + + + if (!tdls_validate || !tdls_validate->vdev) + return -EINVAL; + + if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(tdls_validate->vdev, + &tdls_vdev, + &tdls_soc)) + return -ENOTSUPP; + + /* + * STA or P2P client should be connected and authenticated before + * sending any TDLS frames + */ + if (!tdls_is_vdev_connected(tdls_validate->vdev) || + !tdls_is_vdev_authenticated(tdls_validate->vdev)) { + tdls_err("STA is not connected or not authenticated."); + return -EAGAIN; + } + + /* other than teardown frame, mgmt frames are not sent if disabled */ + if (TDLS_TEARDOWN != tdls_validate->action_code) { + if (!tdls_check_is_tdls_allowed(tdls_validate->vdev)) { + tdls_err("TDLS not allowed, reject MGMT, action = %d", + tdls_validate->action_code); + return -EPERM; + } + /* if tdls_mode is disabled, then decline the peer's request */ + if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { + tdls_notice(QDF_MAC_ADDRESS_STR + " TDLS mode is disabled. action %d declined.", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code); + return -ENOTSUPP; + } + if (tdls_soc->tdls_nss_switch_in_progress) { + tdls_err("nss switch in progress, action %d declined " + QDF_MAC_ADDRESS_STR, + tdls_validate->action_code, + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + return -EAGAIN; + } + } + + if (TDLS_IS_SETUP_ACTION(tdls_validate->action_code)) { + if (NULL != tdls_is_progress(tdls_vdev, + tdls_validate->peer_mac, true)) { + tdls_err("setup is ongoing. action %d declined for " + QDF_MAC_ADDRESS_STR, + tdls_validate->action_code, + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); + return -EPERM; + } + } + + /* + * Discard TDLS Discovery request and setup confirm if violates + * ACM rules + */ + if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code || + TDLS_SETUP_CONFIRM == tdls_validate->action_code)) { + /* call hdd_wmm_is_acm_allowed() */ + if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + tdls_err("admission ctrl set to VI, action %d declined", + tdls_validate->action_code); + return -EPERM; + } + } + + + if (TDLS_SETUP_REQUEST == tdls_validate->action_code || + TDLS_SETUP_RESPONSE == tdls_validate->action_code) { + if (tdls_soc->max_num_tdls_sta <= + tdls_soc->connected_peer_count) { + status = tdls_validate_setup_frames(tdls_soc, + tdls_validate); + if (QDF_STATUS_SUCCESS != status) + return status; + /* fall through to send setup resp + * with failure status code + */ + } else { + curr_peer = + tdls_find_peer(tdls_vdev, + tdls_validate->peer_mac); + if (curr_peer) { + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { + tdls_err(QDF_MAC_ADDRESS_STR " already connected action %d declined.", + QDF_MAC_ADDR_ARRAY( + tdls_validate->peer_mac), + tdls_validate->action_code); + + return -EPERM; + } + } + } + } + + tdls_notice("tdls_mgmt" QDF_MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + tdls_validate->action_code, tdls_validate->dialog_token, + tdls_validate->status_code, tdls_validate->len); + + /*Except teardown responder will not be used so just make 0 */ + tdls_validate->responder = 0; + if (TDLS_TEARDOWN == tdls_validate->action_code) { + temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); + if (!temp_peer) { + tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist", + QDF_MAC_ADDR_ARRAY( + tdls_validate->peer_mac)); + return -EPERM; + } + + if (TDLS_IS_LINK_CONNECTED(temp_peer)) + tdls_validate->responder = temp_peer->is_responder; + else { + tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", + QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), + temp_peer->link_status, + tdls_validate->dialog_token, + tdls_validate->status_code, + tdls_validate->len); + return -EPERM; + } + } + + /* For explicit trigger of DIS_REQ come out of BMPS for + * successfully receiving DIS_RSP from peer. + */ + if ((TDLS_SETUP_RESPONSE == tdls_validate->action_code) || + (TDLS_SETUP_CONFIRM == tdls_validate->action_code) || + (TDLS_DISCOVERY_RESPONSE == tdls_validate->action_code) || + (TDLS_DISCOVERY_REQUEST == tdls_validate->action_code)) { + /* Fw will take care if PS offload is enabled. */ + if (TDLS_DISCOVERY_REQUEST != tdls_validate->action_code) + tdls_set_cap(tdls_vdev, tdls_validate->peer_mac, + TDLS_CAP_SUPPORTED); + } + return 0; +} + QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) { struct wlan_serialization_command cmd = {0,}; @@ -1000,6 +1238,105 @@ error: return status; } +/** + * tdls_process_send_mgmt_rsp() - handle response for send mgmt + * @rsp: TDLS send mgmt response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = rsp->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, + WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("invalid vdev"); + status = QDF_STATUS_E_INVAL; + qdf_mem_free(rsp); + return status; + } + tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_soc || !tdls_vdev) { + tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + status = QDF_STATUS_E_FAILURE; + } + + tdls_release_serialization_command(vdev, WLAN_SER_CMD_TDLS_SEND_MGMT); + + if (legacy_result_success == rsp->status_code) + goto free_rsp; + tdls_err("send mgmt failed. status code(=%d)", rsp->status_code); + status = QDF_STATUS_E_FAILURE; + + if (tdls_soc && tdls_soc->tdls_event_cb) { + ind.vdev = vdev; + ind.status = rsp->status_code; + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); + } + +free_rsp: + qdf_mem_free(rsp); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + return status; +} + +/** + * tdls_send_mgmt_tx_completion() - process tx completion + * @tx_complete: TDLS mgmt completion info + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_send_mgmt_tx_completion( + struct tdls_mgmt_tx_completion_ind *tx_complete) +{ + struct wlan_objmgr_vdev *vdev; + struct wlan_objmgr_psoc *psoc; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc = NULL; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct tdls_osif_indication ind; + + psoc = tx_complete->psoc; + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + tx_complete->session_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("invalid vdev"); + status = QDF_STATUS_E_INVAL; + goto free_tx_complete; + } + + tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + + if (!tdls_soc || !tdls_vdev) { + tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + status = QDF_STATUS_E_FAILURE; + } + + if (tdls_soc && tdls_soc->tdls_event_cb) { + ind.vdev = vdev; + ind.status = tx_complete->tx_complete_status; + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); +free_tx_complete: + qdf_mem_free(tx_complete); + return status; +} + /** * tdls_add_peer_rsp() - handle response for add TDLS peer * @rsp: TDLS add peer response @@ -1139,10 +1476,12 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); + wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); wlan_vdev_obj_unlock(vdev); - if (TDLS_IS_CONNECTED(curr_peer)) { + + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( soc_obj->tdls_tl_peer_data, id, curr_peer->sta_id); @@ -1464,6 +1803,10 @@ static QDF_STATUS tdls_config_force_peer( tdls_set_callback(peer, req->callback); + tdls_set_ct_mode(soc_obj->soc); + if (soc_obj->enable_tdls_connection_tracker) + tdls_implicit_enable(vdev_obj); + return status; error: qdf_mem_free(peer_update_param); @@ -1605,8 +1948,10 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) qdf_mem_free(peer_update_param); goto error; } + tdls_set_ct_mode(soc_obj->soc); + if (!soc_obj->enable_tdls_connection_tracker) + tdls_implicit_disable(vdev_obj); - /*TODO set tdls connection tracker state*/ error: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 8c17dfebd4..ec2f40e107 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -25,6 +25,11 @@ #ifndef _WLAN_TDLS_CMDS_PROCESS_H_ #define _WLAN_TDLS_CMDS_PROCESS_H_ +#define TDLS_IS_SETUP_ACTION(action) \ + ((TDLS_SETUP_REQUEST <= action) && \ + (TDLS_SETUP_CONFIRM >= action)) + + /** * enum tdls_add_oper - add peer type * @TDLS_OPER_NONE: none @@ -37,6 +42,53 @@ enum tdls_add_oper { TDLS_OPER_UPDATE }; +/** + * enum legacy_result_code - defined to comply with tSirResultCodes, need refine + * when mlme converged. + * @legacy_result_success: success + * @legacy_result_max: max result value + */ +enum legacy_result_code { + legacy_result_success, + legacy_result_max = 0x7FFFFFFF +}; + +/** + * struct tdls_send_mgmt_rsp - TDLS Response struct PE --> TDLS module + * same as struct tSirSmeRsp + * @message_type: message type eWNI_SME_TDLS_SEND_MGMT_RSP + * @length: message length + * @session_id: session id + * @transaction_id: transaction id + * @status_code: status code as tSirResultCodes + * @psoc: soc object + */ +struct tdls_send_mgmt_rsp { + uint16_t message_type; + uint16_t length; + uint8_t session_id; + uint16_t transaction_id; + enum legacy_result_code status_code; + struct wlan_objmgr_psoc *psoc; +}; + +/** + * struct tdls_mgmt_tx_completion_ind - TDLS TX completion PE --> TDLS module + * same as struct sSirMgmtTxCompletionInd + * @message_type: message type eWNI_SME_MGMT_FRM_TX_COMPLETION_IND + * @length: message length + * @session_id: session id + * @tx_complete_status: tx complete status + * @psoc: soc object + */ +struct tdls_mgmt_tx_completion_ind { + uint16_t message_type; + uint16_t length; + uint8_t session_id; /* Session ID */ + uint32_t tx_complete_status; + struct wlan_objmgr_psoc *psoc; +}; + /** * struct tdls_add_sta_req - TDLS request struct TDLS module --> PE * same as struct tSirTdlsAddStaReq; @@ -213,6 +265,52 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req); */ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); +/** + * tdls_reset_nss() - reset tdls nss parameters + * @tdls_soc: TDLS soc object + * @action_code: action code + * + * Return: None + */ +void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, + uint8_t action_code); + +/** + * tdls_set_cap() - set TDLS capability type + * @tdls_vdev: tdls vdev object + * @mac: peer mac address + * @cap: TDLS capability type + * + * Return: 0 if successful or negative errno otherwise + */ +int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, + enum tdls_peer_capab cap); + +/** + * tdls_validate_mgmt_request() -validate mgmt request + * @tdls_validate: action frame request + * + * Return: 0 for success or -EINVAL otherwise + */ +int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); + +/** + * tdls_process_send_mgmt_rsp() - handle response for send mgmt + * @rsp: TDLS send mgmt response + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp); + +/** + * tdls_send_mgmt_tx_completion() - process tx completion + * @tx_complete: TDLS mgmt completion info + * + * Return: QDF_STATUS_SUCCESS for success; other values if failed + */ +QDF_STATUS tdls_send_mgmt_tx_completion( + struct tdls_mgmt_tx_completion_ind *tx_complete); + /** * tdls_process_add_peer_rsp() - handle response for delete TDLS peer * @rsp: TDLS delete peer response diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 52ccfcfd20..cb48dd2057 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -52,6 +52,27 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) return true; } +bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev) +{ + struct wlan_objmgr_peer *peer; + bool is_authenticated = false; + + wlan_vdev_obj_lock(vdev); + peer = wlan_vdev_get_bsspeer(vdev); + wlan_vdev_obj_unlock(vdev); + + if (!peer) { + tdls_err("peer is null"); + return false; + } + + wlan_peer_obj_lock(peer); + is_authenticated = wlan_peer_mlme_get_auth_state(peer); + wlan_peer_obj_unlock(peer); + + return is_authenticated; +} + /** * tdls_peer_reset_discovery_processed() - reset discovery status * @tdls_vdev: TDLS vdev object diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index d894794eb5..e497daed2b 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -155,4 +155,21 @@ void tdls_discovery_timeout_peer_cb(void *user_data); * Return: Void */ void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); + +/** + * tdls_is_vdev_connected() -check the vdev connection + * @vdev: vdev oobject + * + * Return: true or false + */ +bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_is_vdev_authenticated() -check the vdev authentication state + * @vdev: vdev oobject + * + * Return: true or false + */ +bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5fef8c76e7..c58d8682b3 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -30,6 +30,8 @@ #include "wlan_tdls_tgt_api.h" #include "wlan_policy_mgr_public_struct.h" #include "wlan_policy_mgr_api.h" +#include "wlan_scan_ucfg_api.h" + /* Global tdls soc pvt object * this is useful for some functions which does not receive either vdev or psoc diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 30ace45119..bfbddf0ded 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -34,6 +34,7 @@ #include #include #include "wlan_serialization_api.h" +#include "wlan_tdls_mgmt.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ @@ -74,7 +75,7 @@ #define tdls_alert(format, args...) \ tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) -#define TDLS_IS_CONNECTED(peer) \ +#define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ (TDLS_LINK_TEARING == (peer)->link_status)) @@ -203,6 +204,10 @@ struct tdls_soc_priv_obj { enum tdls_nss_transition_state tdls_nss_transition_mode; int32_t tdls_teardown_peers_cnt; struct tdls_set_state_info set_state_info; + tdls_rx_callback tdls_rx_cb; + void *tdls_rx_cb_data; + tdls_wmm_check tdls_wmm_cb; + void *tdls_wmm_cb_data; tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 3f28bf0817..f6e27dfd75 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -113,7 +113,6 @@ static QDF_STATUS tdls_process_rx_mgmt( tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); } - if (rx_mgmt->buf[TDLS_PUBLIC_ACTION_FRAME_OFFSET] == TDLS_ACTION_FRAME) { action_frame_type = @@ -127,7 +126,7 @@ static QDF_STATUS tdls_process_rx_mgmt( } } - /* tdls_soc_obj->tdls_rx_cb ==> wlan_tdls_rx_callback() */ + /* tdls_soc_obj->tdls_rx_cb ==> wlan_cfg80211_tdls_rx_callback() */ if (tdls_soc_obj && tdls_soc_obj->tdls_rx_cb) tdls_soc_obj->tdls_rx_cb(tdls_soc_obj->tdls_rx_cb_data, rx_mgmt); @@ -157,7 +156,6 @@ QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) if (vdev) { tdls_debug("tdls rx mgmt frame received"); - tdls_vdev = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); if (tdls_vdev) @@ -175,6 +173,7 @@ QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; + QDF_STATUS status; int num_of_entries; diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 94e6d11f97..3d3e6dd54a 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -28,6 +28,24 @@ /* default tdls serialize timeout is set to 10 secs */ #define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 +#define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24 +#define TDLS_PUBLIC_ACTION_FRAME 4 +#define TDLS_PUBLIC_ACTION_DISC_RESP 14 +#define TDLS_ACTION_FRAME 12 +#define TDLS_80211_PEER_ADDR_OFFSET (TDLS_PUBLIC_ACTION_FRAME + \ + QDF_MAC_ADDR_SIZE) +#define TDLS_ACTION_FRAME_TYPE_MAX 11 + +/** + * struct tdls_rx_mgmt_event - tdls rx mgmt frame event + * @tdls_soc_obj: tdls soc private object + * @rx_mgmt: tdls rx mgmt frame structure + */ +struct tdls_rx_mgmt_event { + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_rx_mgmt_frame *rx_mgmt; +}; + /* * struct tdls_send_mgmt_request - tdls management request * @message_type: type of pe message @@ -70,5 +88,26 @@ struct tdls_send_mgmt_request { */ QDF_STATUS tdls_process_mgmt_req( struct tdls_action_frame_request *tdls_mgmt_req); + +/** + * tdls_mgmt_rx_ops() - register or unregister rx callback + * @psoc: psoc object + * @isregister: register if true, unregister if false + * + * This function registers or unregisters rx callback to mgmt txrx + * component. + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, + bool isregister); + +/** + * tdls_process_rx_frame() - process tdls rx frames + * @msg: scheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg); #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4d4b7be416..36e3a4676c 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -29,6 +29,8 @@ #include #include #include +#include + #define WLAN_TDLS_STA_MAX_NUM 8 #define WLAN_TDLS_STA_P_UAPSD_OFFCHAN_MAX_NUM 1 @@ -59,7 +61,7 @@ #define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 /** Maximum time(ms) to wait for tdls mgmt to complete **/ -#define WAIT_TIME_TDLS_MGMT 11000 +#define WAIT_TIME_FOR_TDLS_MGMT 11000 #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -252,7 +254,7 @@ enum tdls_event_msg_type { TDLS_SHOULD_DISCOVER = 0, TDLS_SHOULD_TEARDOWN, TDLS_PEER_DISCONNECTED, - TDLS_CONNECTION_TRACKER_NOTIFY, + TDLS_CONNECTION_TRACKER_NOTIFY }; /** diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index dbc8c0683f..4357241a4e 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -67,6 +67,22 @@ QDF_STATUS tgt_tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, struct sta_uapsd_trig_params *params); +/** + * tgt_tdls_send_mgmt_rsp() - process tdls mgmt response + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg); + +/** + * tgt_tdls_send_mgmt_tx_completion() -process tx completion message + * @pmsg: sheduler msg + * + * Return: QDF_STATUS + */ +QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg); + /** * tgt_tdls_del_peer_rsp() - handle TDLS del peer response * @pmsg: sheduler msg @@ -111,4 +127,23 @@ QDF_STATUS tgt_tdls_unregister_ev_handler(struct wlan_objmgr_psoc *psoc); QDF_STATUS tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, struct tdls_event_info *info); + +/** + * tgt_tdls_mgmt_frame_rx_cb() - callback for rx mgmt frame + * @psoc: soc context + * @peer: peer context + * @buf: rx buffer + * @mgmt_rx_params: mgmt rx parameters + * @frm_type: frame type + * + * This function gets called from mgmt tx/rx component when rx mgmt + * received. + * + * Return: QDF_STATUS_SUCCESS + */ +QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 78a198b2a7..a55f6d1341 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -87,6 +87,36 @@ QDF_STATUS tgt_tdls_set_uapsd(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_SUCCESS; } +QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_send_mgmt_tx_completion(pmsg->bodyptr); + + return status; +} + +QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + + if (!pmsg || !pmsg->bodyptr) { + tdls_err("msg: 0x%p", pmsg); + QDF_ASSERT(0); + return QDF_STATUS_E_NULL_VALUE; + } + + status = tdls_process_send_mgmt_rsp(pmsg->bodyptr); + + return status; +} + QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -183,3 +213,124 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, return status; } + +static +QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type) +{ + struct tdls_rx_mgmt_frame *rx_mgmt; + struct tdls_rx_mgmt_event *rx_mgmt_event; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct scheduler_msg msg; + struct wlan_objmgr_vdev *vdev; + uint32_t vdev_id; + uint8_t *pdata; + QDF_STATUS status; + + tdls_soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, + WLAN_UMAC_COMP_TDLS); + if (!tdls_soc_obj) { + tdls_err("tdls ctx is NULL, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + + if (!peer) { + vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID); + if (!vdev) { + tdls_err("current tdls vdev is null, can't get vdev id"); + return QDF_STATUS_E_FAILURE; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); + } else { + wlan_peer_obj_lock(peer); + vdev = wlan_peer_get_vdev(peer); + wlan_peer_obj_unlock(peer); + if (!vdev) { + tdls_err("vdev is NULL in peer, drop this frame"); + return QDF_STATUS_E_FAILURE; + } + wlan_vdev_obj_lock(vdev); + vdev_id = wlan_vdev_get_id(vdev); + wlan_vdev_obj_unlock(vdev); + } + + rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); + if (!rx_mgmt_event) { + tdls_err("Failed to allocate rx mgmt event"); + return QDF_STATUS_E_NOMEM; + } + + rx_mgmt = qdf_mem_malloc(sizeof(*rx_mgmt) + + mgmt_rx_params->buf_len); + if (!rx_mgmt) { + tdls_err("Failed to allocate rx mgmt frame"); + qdf_mem_free(rx_mgmt_event); + return QDF_STATUS_E_NOMEM; + } + + pdata = (uint8_t *)qdf_nbuf_data(buf); + rx_mgmt->frame_len = mgmt_rx_params->buf_len; + rx_mgmt->rx_chan = mgmt_rx_params->channel; + rx_mgmt->vdev_id = vdev_id; + rx_mgmt->frm_type = frm_type; + rx_mgmt->rx_rssi = mgmt_rx_params->rssi; + + rx_mgmt_event->rx_mgmt = rx_mgmt; + rx_mgmt_event->tdls_soc_obj = tdls_soc_obj; + qdf_mem_copy(rx_mgmt->buf, pdata, mgmt_rx_params->buf_len); + msg.type = TDLS_EVENT_RX_MGMT; + msg.bodyptr = rx_mgmt_event; + msg.callback = tdls_process_rx_frame; + status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + + qdf_nbuf_free(buf); + + return status; +} + +QDF_STATUS tgt_tdls_mgmt_frame_rx_cb( + struct wlan_objmgr_psoc *psoc, + struct wlan_objmgr_peer *peer, + qdf_nbuf_t buf, + struct mgmt_rx_event_params *mgmt_rx_params, + enum mgmt_frame_type frm_type) +{ + QDF_STATUS status; + + tdls_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + + + if (!buf) { + tdls_err("rx frame buff is null buf:%p", buf); + return QDF_STATUS_E_INVAL; + } + + if (!mgmt_rx_params || !psoc) { + tdls_err("input is NULL mgmt_rx_params:%p psoc:%p, peer:%p", + mgmt_rx_params, psoc, peer); + status = QDF_STATUS_E_INVAL; + goto release_nbuf; + } + + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); + if (QDF_STATUS_SUCCESS != status) + goto release_nbuf; + + status = tgt_tdls_mgmt_frame_process_rx_cb(psoc, peer, buf, + mgmt_rx_params, frm_type); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); + + if (QDF_STATUS_SUCCESS != status) +release_nbuf: + qdf_nbuf_free(buf); + return status; +} + diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 1e4afdbfaa..ecef61fdae 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -194,6 +194,12 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + soc_obj->tdls_rx_cb = req->tdls_rx_cb; + soc_obj->tdls_rx_cb_data = req->tdls_rx_cb_data; + + soc_obj->tdls_wmm_cb = req->tdls_wmm_cb; + soc_obj->tdls_wmm_cb_data = req->tdls_wmm_cb_data; + soc_obj->tdls_event_cb = req->tdls_event_cb; soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; @@ -256,9 +262,14 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) tdls_scan_serialization_comp_info_cb); if (QDF_STATUS_SUCCESS != status) { tdls_err("Serialize scan cmd register failed "); - status = QDF_STATUS_E_FAILURE; + return status; } + /* register callbacks with tx/rx mgmt */ + status = tdls_mgmt_rx_ops(psoc, true); + if (status != QDF_STATUS_SUCCESS) + tdls_err("Failed to register mgmt rx callback, status:%d", + status); return status; } @@ -647,4 +658,6 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, tdls_update_tx_pkt_cnt(vdev, mac_addr); wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + } + From ce5880e182f4cae6b2c3e4c49d56d14c680a7fe6 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 17 Apr 2017 21:53:42 -0700 Subject: [PATCH 14/89] qcacmn: Add TDLS off channel changes for TDLS UMAC Add TDLS offchannel and related osif changes in TDLS UMAC component. Change-Id: Ic562709eb8a6361322860c4f7333633a7894af99 CRs-Fixed: 2034220 --- core/src/wlan_tdls_cmds_process.c | 2 +- core/src/wlan_tdls_cmds_process.h | 10 + core/src/wlan_tdls_ct.c | 384 ++++++++++++++++++++++ core/src/wlan_tdls_ct.h | 22 ++ core/src/wlan_tdls_main.c | 20 ++ core/src/wlan_tdls_main.h | 15 + core/src/wlan_tdls_peer.c | 2 +- core/src/wlan_tdls_peer.h | 14 + dispatcher/inc/wlan_tdls_public_structs.h | 19 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 8 + dispatcher/src/wlan_tdls_ucfg_api.c | 22 ++ 11 files changed, 515 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 26594e3f37..35cd7f3e7d 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -43,7 +43,7 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) * * Return: None. */ -static void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) +void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj) { if (soc_obj->connected_peer_count) soc_obj->connected_peer_count--; diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index ec2f40e107..5e2c035084 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -365,4 +365,14 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); */ int tdls_set_responder(struct tdls_set_responder_req *set_req); +/** + * tdls_decrement_peer_count() - decrement connected TDLS peer counter + * @soc_obj: TDLS soc object + * + * Used in scheduler thread context, no lock needed. + * + * Return: None. + */ +void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj); + #endif diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index cb48dd2057..3b5b554fb8 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -25,6 +25,7 @@ #include "wlan_tdls_main.h" #include "wlan_tdls_peer.h" #include "wlan_tdls_ct.h" +#include "wlan_tdls_cmds_process.h" bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) { @@ -936,3 +937,386 @@ void tdls_ct_handler(void *user_data) WLAN_TDLS_NB_ID); } +/** + * tdls_set_tdls_offchannel() - set tdls off-channel number + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel number + * + * This function sets tdls off-channel number + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, + int offchannel) +{ + uint32_t tdls_feature_flags; + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + + if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && + (TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_current_mode || + TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_current_mode)) { + if (offchannel < TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN || + offchannel > TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX) { + tdls_err("Invalid tdls off channel %u", offchannel); + return -EINVAL; + } + } else { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + tdls_notice("change tdls off channel from %d to %d", + tdls_soc->tdls_off_channel, offchannel); + tdls_soc->tdls_off_channel = offchannel; + return 0; +} + +/** + * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel offset + * + * This function sets 2nd tdls off-channel offset + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, + int offchanoffset) +{ + uint32_t tdls_feature_flags; + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + + if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) || + TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + + tdls_soc->tdls_channel_offset = 0; + + switch (offchanoffset) { + case TDLS_SEC_OFFCHAN_OFFSET_0: + tdls_soc->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: + case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: + tdls_soc->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_80: + tdls_soc->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + break; + case TDLS_SEC_OFFCHAN_OFFSET_160: + tdls_soc->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + break; + default: + tdls_err("Invalid tdls secondary off channel offset %d", + offchanoffset); + return -EINVAL; + } /* end switch */ + + tdls_notice("change tdls secondary off channel offset to 0x%x", + tdls_soc->tdls_channel_offset); + return 0; +} + +/** + * tdls_set_tdls_offchannelmode() - set tdls off-channel mode + * @adapter: Pointer to the HDD adapter + * @offchanmode: tdls off-channel mode + * + * This function sets tdls off-channel mode + * + * Return: 0 on success; negative errno otherwise + */ +static +int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, + int offchanmode) +{ + struct tdls_peer *conn_peer = NULL; + struct tdls_channel_switch_params chan_switch_params; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + int ret_value = 0; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + uint32_t tdls_feature_flags; + + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + + if (status != QDF_STATUS_SUCCESS) + return -EINVAL; + + + if (offchanmode < ENABLE_CHANSWITCH || + offchanmode > DISABLE_CHANSWITCH) { + tdls_err("Invalid tdls off channel mode %d", offchanmode); + return -EINVAL; + } + + if (tdls_is_vdev_connected(vdev)) { + tdls_err("tdls off channel req in not associated state %d", + offchanmode); + return -EPERM; + } + + tdls_feature_flags = tdls_soc->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) || + TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_err("Either TDLS or TDLS Off-channel is not enabled"); + return -ENOTSUPP; + } + + conn_peer = tdls_find_first_connected_peer(tdls_vdev); + if (NULL == conn_peer) { + tdls_err("No TDLS Connected Peer"); + return -EPERM; + } + + tdls_notice("TDLS Channel Switch in swmode=%d tdls_off_channel %d offchanoffset %d", + offchanmode, tdls_soc->tdls_off_channel, + tdls_soc->tdls_channel_offset); + + switch (offchanmode) { + case ENABLE_CHANSWITCH: + if (tdls_soc->tdls_off_channel && + tdls_soc->tdls_channel_offset) { + chan_switch_params.tdls_off_ch = + tdls_soc->tdls_off_channel; + chan_switch_params.tdls_off_ch_bw_offset = + tdls_soc->tdls_channel_offset; + chan_switch_params.oper_class = + tdls_find_opclass(tdls_soc->soc, + chan_switch_params.tdls_off_ch, + chan_switch_params.tdls_off_ch_bw_offset); + } else { + tdls_err("TDLS off-channel parameters are not set yet!!!"); + return -EINVAL; + + } + break; + case DISABLE_CHANSWITCH: + chan_switch_params.tdls_off_ch = 0; + chan_switch_params.tdls_off_ch_bw_offset = 0; + chan_switch_params.oper_class = 0; + break; + default: + tdls_err("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d", + offchanmode, tdls_soc->tdls_off_channel, + tdls_soc->tdls_channel_offset); + return -EINVAL; + } /* end switch */ + + chan_switch_params.vdev_id = tdls_vdev->session_id; + chan_switch_params.tdls_sw_mode = offchanmode; + chan_switch_params.is_responder = + conn_peer->is_responder; + qdf_mem_copy(&chan_switch_params.peer_mac_addr, + &conn_peer->peer_mac.bytes, + QDF_MAC_ADDR_SIZE); + tdls_notice("Peer " QDF_MAC_ADDRESS_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", + QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), + chan_switch_params.vdev_id, + chan_switch_params.tdls_off_ch, + chan_switch_params.tdls_off_ch_bw_offset, + chan_switch_params.tdls_sw_mode, + chan_switch_params.is_responder); + + status = tdls_set_offchan_mode(tdls_soc->soc, + &chan_switch_params); + + if (status != QDF_STATUS_SUCCESS) { + tdls_err("Failed to send channel switch request to wmi"); + return -EINVAL; + } + + tdls_soc->tdls_fw_off_chan_mode = offchanmode; + + if (ENABLE_CHANSWITCH == offchanmode) { + conn_peer = tdls_find_first_connected_peer(tdls_vdev); + if (NULL == conn_peer) { + tdls_err("No TDLS Connected Peer"); + return -EPERM; + } + conn_peer->pref_off_chan_num = + chan_switch_params.tdls_off_ch; + conn_peer->op_class_for_pref_off_chan = + chan_switch_params.oper_class; + } + + return ret_value; +} + +/** + * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * @vdev: vdev object + * @tdls_soc: tdls soc object + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +static +QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, + struct tdls_soc_priv_obj *tdls_soc) +{ + struct wlan_objmgr_peer *peer; + struct tdls_del_all_tdls_peers *del_msg; + struct scheduler_msg msg; + QDF_STATUS status; + + + del_msg = qdf_mem_malloc(sizeof(*del_msg)); + if (NULL == del_msg) { + tdls_err("memory alloc failed"); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_zero(del_msg, sizeof(*del_msg)); + + peer = wlan_vdev_get_bsspeer(vdev); + if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, + WLAN_TDLS_SB_ID)) { + return QDF_STATUS_E_FAILURE; + } + + qdf_mem_copy(del_msg->bssid.bytes, + wlan_peer_get_macaddr(peer), QDF_MAC_ADDR_SIZE); + + del_msg->msg_type = tdls_soc->tdls_del_all_peers; + del_msg->msg_len = (uint16_t) sizeof(*del_msg); + + /* Send the request to PE. */ + qdf_mem_zero(&msg, sizeof(msg)); + + tdls_debug("sending delete all peers req to PE "); + + msg.type = del_msg->msg_type; + msg.bodyptr = del_msg; + + status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + + wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); + return status; +} + +void tdls_disable_offchan_and_teardown_links( + struct wlan_objmgr_vdev *vdev) +{ + uint16_t connected_tdls_peers = 0; + uint8_t staidx; + struct tdls_peer *curr_peer = NULL; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + QDF_STATUS status; + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("tdls objects are NULL "); + return; + } + + if (TDLS_SUPPORT_SUSPENDED >= tdls_soc->tdls_current_mode) { + tdls_notice("TDLS mode %d is disabled OR not suspended now", + tdls_soc->tdls_current_mode); + return; + } + + connected_tdls_peers = tdls_soc->connected_peer_count; + + if (!connected_tdls_peers) { + tdls_notice("No TDLS connected peers to delete"); + return; + } + + /* TDLS is not supported in case of concurrency. + * Disable TDLS Offchannel in FW to avoid more + * than two concurrent channels and generate TDLS + * teardown indication to supplicant. + * Below function Finds the first connected peer and + * disables TDLS offchannel for that peer. + * FW enables TDLS offchannel only when there is + * one TDLS peer. When there are more than one TDLS peer, + * there will not be TDLS offchannel in FW. + * So to avoid sending multiple request to FW, for now, + * just invoke offchannel mode functions only once + */ + tdls_set_tdls_offchannel(tdls_soc, + tdls_soc->tdls_configs.tdls_pre_off_chan_num); + tdls_set_tdls_secoffchanneloffset(tdls_soc, + TDLS_SEC_OFFCHAN_OFFSET_40PLUS); + tdls_set_tdls_offchannelmode(vdev, DISABLE_CHANSWITCH); + + /* Send Msg to PE for deleting all the TDLS peers */ + tdls_delete_all_tdls_peers(vdev, tdls_soc); + + for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; + staidx++) { + if (!tdls_soc->tdls_conn_info[staidx].sta_id) + continue; + + curr_peer = tdls_find_all_peer(tdls_soc, + tdls_soc->tdls_conn_info[staidx].peer_mac.bytes); + if (!curr_peer) + continue; + + tdls_notice("indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + + /* Indicate teardown to supplicant */ + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + /* + * Del Sta happened already as part of tdls_delete_all_tdls_peers + * Hence clear tdls vdev data structure. + */ + tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); + + if (tdls_soc->tdls_dereg_tl_peer) + tdls_soc->tdls_dereg_tl_peer( + tdls_soc->tdls_tl_peer_data, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); + + tdls_decrement_peer_count(tdls_soc); + tdls_soc->tdls_conn_info[staidx].sta_id = 0; + tdls_soc->tdls_conn_info[staidx].session_id = 255; + + qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, + sizeof(struct qdf_mac_addr)); + } +} + +void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_osif_indication indication; + struct tdls_soc_priv_obj *tdls_soc; + struct wlan_objmgr_vdev *tdls_vdev_obj; + + if (!vdev) { + QDF_ASSERT(0); + return; + } + + tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc) + return; + + /* Get the tdls specific vdev and clear the links */ + tdls_vdev_obj = tdls_get_vdev(tdls_soc->soc, WLAN_TDLS_SB_ID); + if (tdls_vdev_obj) { + tdls_disable_offchan_and_teardown_links(tdls_vdev_obj); + wlan_objmgr_vdev_release_ref(tdls_vdev_obj, WLAN_TDLS_SB_ID); + } + + indication.vdev = vdev; + + if (tdls_soc->tdls_event_cb) + tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, + TDLS_EVENT_TEARDOWN_LINKS_DONE, + &indication); +} diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index e497daed2b..63e3063780 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -31,6 +31,10 @@ */ #define TDLS_DISCOVERY_TIMEOUT_ERE_UPDATE 1000 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165 +#define TDLS_PREFERRED_OFF_CHANNEL_NUM_DEFAULT 36 + /** * tdls_is_vdev_connected() - check the vdev is connected to ap * @vdev: vdev object manager @@ -172,4 +176,22 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev); */ bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev); +/** + * tdls_teardown_connections() -teardown and delete all the tdls peers + * @vdev: vdev oobject + * + * Return: true or false + */ +void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_disable_offchan_and_teardown_links - Disable offchannel + * and teardown TDLS links + * @tdls_soc : tdls soc object + * + * Return: None + */ +void tdls_disable_offchan_and_teardown_links( + struct wlan_objmgr_vdev *vdev); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index c58d8682b3..f98d993579 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -287,6 +287,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SESSION_DECREMENT: tdls_process_policy_mgr_notification(msg->bodyptr); break; + case TDLS_CMD_TEARDOWN_LINKS: + tdls_teardown_connections(msg->bodyptr); + break; default: break; } @@ -468,6 +471,20 @@ static void tdls_state_param_setting_dump(struct tdls_info *info) } +QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param) +{ + QDF_STATUS status; + + /* wmi_unified_set_tdls_offchan_mode_cmd() will be called directly */ + status = tgt_tdls_set_offchan_mode(psoc, param); + + if (!QDF_IS_STATUS_SUCCESS(status)) + status = QDF_STATUS_E_FAILURE; + + return status; +} + /** * tdls_update_fw_tdls_state() - update tdls status info * @tdls_soc_obj: TDLS soc object @@ -745,12 +762,15 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_soc_obj->set_state_info.set_state_cnt); /* disable off channel and teardown links */ /* Go through the peer list and delete them */ + tdls_disable_offchan_and_teardown_links(tdls_vdev_obj->vdev); tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id; } else { tdls_info_to_fw->vdev_id = session_id; } + /* record the session id in vdev context */ + tdls_vdev_obj->session_id = session_id; tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; tdls_info_to_fw->tdls_options = 0; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index bfbddf0ded..f6096f2ef3 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -180,6 +180,7 @@ struct tdls_set_state_info { * @tdls_add_sta_req: store eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS * @tdls_idle_peer_data: provide information about idle peer * @tdls_ct_spinlock: connection tracker spin lock */ @@ -221,6 +222,7 @@ struct tdls_soc_priv_obj { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + uint16_t tdls_del_all_peers; struct tdls_ct_idle_peer_data tdls_idle_peer_data; qdf_spinlock_t tdls_ct_spinlock; }; @@ -255,6 +257,7 @@ struct tdls_vdev_priv_obj { ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE]; uint8_t valid_mac_entries; uint32_t magic; + uint8_t session_id; qdf_list_t tx_queue; }; @@ -667,4 +670,16 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); void tdls_scan_serialization_comp_info_cb( union wlan_serialization_rules_info *comp_info); +/** + * tdls_set_offchan_mode() - update tdls status info + * @psoc: soc object + * @param: channel switch params + * + * send message to WMI to set TDLS off channel in f/w + * + * Return: QDF_STATUS. + */ +QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, + struct tdls_channel_switch_params *param); + #endif diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index a89736fb95..56e5ec715e 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -125,7 +125,7 @@ tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr) return tdls_search_param.peer; } -static uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, +uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel, uint8_t bw_offset) { char country[REG_ALPHA2_LEN + 1]; diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h index 511b4d4ed0..7a510c1dac 100644 --- a/core/src/wlan_tdls_peer.h +++ b/core/src/wlan_tdls_peer.h @@ -84,6 +84,20 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, struct tdls_peer * tdls_find_all_peer(struct tdls_soc_priv_obj *soc_obj, const uint8_t *macaddr); +/** + * tdls_find_all_peer() - find peer matching the input MACaddr in soc range + * @soc_obj: TDLS soc object + * @channel:channel number + * @bw_offset: offset to bandwidth + * + * This is in scheduler thread context, no lock required. + * + * Return: Operating class + */ +uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, + uint8_t channel, + uint8_t bw_offset); + /** * tdls_find_first_connected_peer() - find the 1st connected tdls peer from vdev * @vdev_obj: tdls vdev object diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 36e3a4676c..3632af50a1 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -29,7 +29,6 @@ #include #include #include -#include #define WLAN_TDLS_STA_MAX_NUM 8 @@ -63,6 +62,9 @@ /** Maximum time(ms) to wait for tdls mgmt to complete **/ #define WAIT_TIME_FOR_TDLS_MGMT 11000 +/** Maximum waittime for TDLS teardown links **/ +#define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 + #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -188,6 +190,7 @@ enum tdls_command_type { TDLS_CMD_SET_TDLS_MODE, TDLS_CMD_SESSION_INCREMENT, TDLS_CMD_SESSION_DECREMENT, + TDLS_CMD_TEARDOWN_LINKS, }; /** @@ -210,6 +213,7 @@ enum tdls_event_type { TDLS_EVENT_DISCOVERY_REQ, TDLS_EVENT_TEARDOWN_REQ, TDLS_EVENT_SETUP_REQ, + TDLS_EVENT_TEARDOWN_LINKS_DONE, }; /** @@ -547,6 +551,7 @@ struct tdls_start_params { uint16_t tdls_add_sta_req; uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; + uint16_t tdls_del_all_peers; tdls_rx_callback tdls_rx_cb; void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; @@ -1001,4 +1006,16 @@ struct tdls_set_mode_params { enum tdls_disable_sources source; }; +/** + * struct tdls_del_all_tdls_peers - delete all tdls peers + * @msg_type: type of message + * @msg_len: length of message + * @bssid: bssid of peer device + */ +struct tdls_del_all_tdls_peers { + uint16_t msg_type; + uint16_t msg_len; + struct qdf_mac_addr bssid; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 6c7d117b44..5d99669740 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -138,6 +138,14 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( */ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); +/** + * ucfg_tdls_teardown_links() - teardown all TDLS links + * @vdev: vdev object manager + * + * Return: None + */ +QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev); + /** * ucfg_tdls_notify_sta_connect() - notify sta connect * @notify_info: sta notification info diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index ecef61fdae..4412c58782 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -216,6 +216,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_add_sta_req = req->tdls_add_sta_req; soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; + soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; @@ -238,6 +239,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, else soc_obj->tdls_current_mode = TDLS_SUPPORT_IMP_MODE; + soc_obj->tdls_last_mode = soc_obj->tdls_current_mode; return QDF_STATUS_SUCCESS; } @@ -538,6 +540,26 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) return status; } +QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0, }; + + if (!vdev) { + tdls_err("vdev is NULL "); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_notice("Enter "); + + msg.bodyptr = vdev; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_TEARDOWN_LINKS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + tdls_notice("Exit "); + return status; +} + QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify_info) { From 1ac9c552b2a2c76b626c6a0511c2210c76e0743b Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 20 Apr 2017 10:33:39 -0700 Subject: [PATCH 15/89] qcacmn: Fix TDLS UMAC memory init issues scheduler message structure needs to be initialised to zero before populating it contents. Init scheduler msg structure to zero during the structure declaration. Change-Id: Ib6281b7d3b0a103be5adf65d12c20a28f48065f5 CRs-Fixed: 2034220 --- core/src/wlan_tdls_ct.c | 2 +- core/src/wlan_tdls_main.c | 5 ++--- core/src/wlan_tdls_mgmt.c | 3 +-- dispatcher/src/wlan_tdls_tgt_api.c | 2 +- dispatcher/src/wlan_tdls_ucfg_api.c | 8 ++++++++ 5 files changed, 13 insertions(+), 7 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 3b5b554fb8..2e8b60e8b6 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1165,7 +1165,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, { struct wlan_objmgr_peer *peer; struct tdls_del_all_tdls_peers *del_msg; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; QDF_STATUS status; diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index f98d993579..5e2bdbf79a 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -805,10 +805,8 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_state_param_setting_dump(tdls_info_to_fw); status = tdls_update_fw_tdls_state(tdls_soc_obj, tdls_info_to_fw); - if (QDF_STATUS_SUCCESS != status) { - qdf_mem_free(tdls_info_to_fw); + if (QDF_STATUS_SUCCESS != status) goto done; - } if (sta_connect_event) { tdls_soc_obj->set_state_info.set_state_cnt++; @@ -828,6 +826,7 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); done: + qdf_mem_free(tdls_info_to_fw); tdls_process_session_update(tdls_soc_obj->soc, TDLS_CMD_SESSION_INCREMENT); return; diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index f6e27dfd75..ed8848e099 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -225,8 +225,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( struct wlan_objmgr_peer *peer; struct tdls_soc_priv_obj *tdls_soc_obj; QDF_STATUS status = QDF_STATUS_SUCCESS; - - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct tdls_send_mgmt_request *tdls_mgmt_req; if (!action_req || !action_req->vdev) diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index a55f6d1341..cd097dbf86 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -225,7 +225,7 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( struct tdls_rx_mgmt_frame *rx_mgmt; struct tdls_rx_mgmt_event *rx_mgmt_event; struct tdls_soc_priv_obj *tdls_soc_obj; - struct scheduler_msg msg; + struct scheduler_msg msg = {0}; struct wlan_objmgr_vdev *vdev; uint32_t vdev_id; uint8_t *pdata; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 4412c58782..2dca630659 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -285,7 +285,15 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; } + status = tgt_tdls_unregister_ev_handler(psoc); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to unregister tdls event handler"); + + status = tdls_mgmt_rx_ops(psoc, false); + if (QDF_IS_STATUS_ERROR(status)) + tdls_err("Failed to unregister mgmt rx callback"); + soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { From 8becb02681403100cf888cf69b324d57187f3607 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 24 Apr 2017 16:26:50 -0700 Subject: [PATCH 16/89] qcacmn: Fix excessive logging problem in TDLS TDLS registered for optional action frames to print the information about unknown peer commands. This causes problem in the system with too many logs. Remove the optional action frames registration from the TDLS component. Change-Id: Iec2ee86ae1b3139858f6a1ff5b96477bc6dae169 CRs-Fixed: 2037911 --- core/src/wlan_tdls_mgmt.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index ed8848e099..2bef1af535 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -172,28 +172,23 @@ QDF_STATUS tdls_process_rx_frame(struct scheduler_msg *msg) QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, bool isregister) { - struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info[3]; - + struct mgmt_txrx_mgmt_frame_cb_info frm_cb_info; QDF_STATUS status; int num_of_entries; tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); - frm_cb_info[0].frm_type = MGMT_PROBE_REQ; - frm_cb_info[0].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - frm_cb_info[1].frm_type = MGMT_ACTION_TDLS_DISCRESP; - frm_cb_info[1].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - frm_cb_info[2].frm_type = MGMT_ACTION_VENDOR_SPECIFIC; - frm_cb_info[2].mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; - num_of_entries = 3; + frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP; + frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; + num_of_entries = 1; if (isregister) status = wlan_mgmt_txrx_register_rx_cb(psoc, - WLAN_UMAC_COMP_TDLS, frm_cb_info, + WLAN_UMAC_COMP_TDLS, &frm_cb_info, num_of_entries); else status = wlan_mgmt_txrx_deregister_rx_cb(psoc, - WLAN_UMAC_COMP_TDLS, frm_cb_info, + WLAN_UMAC_COMP_TDLS, &frm_cb_info, num_of_entries); return status; From 7c0093d955a695850ae0867c0daf3200ccf0d1a8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 26 Apr 2017 13:26:47 -0700 Subject: [PATCH 17/89] qcacmn: Update address search flags for TDLS Add support to set address search flags in WLAN Tx Descriptor for TDLS operation Change-Id: Iafb15fb1efd84a4bef436062368401a5496e4468 CRs-Fixed: 2041759 --- core/src/wlan_tdls_cmds_process.c | 14 ++++++++++++++ core/src/wlan_tdls_ct.c | 7 +++++++ core/src/wlan_tdls_main.h | 3 +++ dispatcher/inc/wlan_tdls_public_structs.h | 13 +++++++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 38 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 35cd7f3e7d..80a7ef3873 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1693,6 +1693,13 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) tdls_increment_peer_count(soc_obj); feature = soc_obj->tdls_configs.tdls_feature_flags; + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + ((peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + tdls_debug("TDLS buffer sta: %d, uapsd_mask %d", TDLS_IS_BUFFER_STA_ENABLED(feature), soc_obj->tdls_configs.tdls_uapsd_mask); @@ -1911,6 +1918,13 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) tdls_set_peer_link_status(peer, TDLS_LINK_TEARING, TDLS_LINK_UNSPECIFIED); + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + ((peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + if (soc_obj->tdls_event_cb) { qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); ind.vdev = vdev; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2e8b60e8b6..d6e73f6974 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -536,6 +536,13 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, TDLS_LINK_UNSPECIFIED); tdls_notice("Teardown reason %d", reason); + if (tdls_soc->tdls_dp_vdev_update) + tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc, + curr_peer->sta_id, + tdls_soc->tdls_update_dp_vdev_flags, + ((curr_peer->link_status == + TDLS_LINK_CONNECTED) ? true : false)); + indication.reason = reason; indication.vdev = tdls_vdev->vdev; qdf_mem_copy(indication.peer_mac, curr_peer->peer_mac.bytes, diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index f6096f2ef3..b250c4d3d8 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -181,6 +181,7 @@ struct tdls_set_state_info { * @tdls_del_sta_req: store eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: store WMA_UPDATE_TDLS_PEER_STATE value * @tdls_del_all_peers:store eWNI_SME_DEL_ALL_TDLS_PEERS + * @tdls_update_dp_vdev_flags store CDP_UPDATE_TDLS_FLAGS * @tdls_idle_peer_data: provide information about idle peer * @tdls_ct_spinlock: connection tracker spin lock */ @@ -215,6 +216,7 @@ struct tdls_soc_priv_obj { void *tdls_evt_cb_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; @@ -223,6 +225,7 @@ struct tdls_soc_priv_obj { uint16_t tdls_del_sta_req; 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/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3632af50a1..974fca313b 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -530,6 +530,14 @@ typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); + +/* This callback is used to update datapath vdev flags */ +typedef QDF_STATUS +(*tdls_dp_vdev_update_flags_callback)(void *cbk_data, + uint8_t sta_id, + uint32_t vdev_param, + bool is_link_up); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -537,12 +545,15 @@ typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, * @tdls_add_sta_req: pass eWNI_SME_TDLS_ADD_STA_REQ value * @tdls_del_sta_req: pass eWNI_SME_TDLS_DEL_STA_REQ value * @tdls_update_peer_state: pass WMA_UPDATE_TDLS_PEER_STATE value + * @tdls_del_all_peers: pass eWNI_SME_DEL_ALL_TDLS_PEERS + * @tdls_update_dp_vdev_flags: pass CDP_UPDATE_TDLS_FLAGS * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data * @tdls_reg_tl_peer: tdls register tdls peer * @tdls_dereg_tl_peer: tdls deregister tdls peer + * @tdls_dp_vdev_update: update vdev flags in datapath * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { @@ -552,6 +563,7 @@ struct tdls_start_params { uint16_t tdls_del_sta_req; uint16_t tdls_update_peer_state; uint16_t tdls_del_all_peers; + uint32_t tdls_update_dp_vdev_flags; tdls_rx_callback tdls_rx_cb; void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; @@ -562,6 +574,7 @@ struct tdls_start_params { void *tx_ack_cnf_cb_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; + tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; void *tdls_tl_peer_data; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 2dca630659..427c183ae4 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -217,6 +217,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_del_sta_req = req->tdls_del_sta_req; soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; + soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; From 952df1941822642b6a5b31722b154cc9c416750e Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 15 May 2017 20:28:05 -0700 Subject: [PATCH 18/89] qcacmn: Fix TDLS set state cmd sequence for roaming Firmware expects TDLS set state cmd before vdev stop, but the cmd is going out of sequence during roaming and induce crash in the system. Send the TDLS set state cmd with correct sequence. Change-Id: Ie106b8a8cebaa7f107c9eff67dda924b231162da CRs-Fixed: 2048036 --- core/src/wlan_tdls_main.c | 106 +++++++++++++++++++--------- core/src/wlan_tdls_main.h | 14 ++++ dispatcher/inc/wlan_tdls_tgt_api.h | 12 ++++ dispatcher/src/wlan_tdls_tgt_api.c | 21 ++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 119 insertions(+), 35 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5e2bdbf79a..437b51f5fc 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -623,20 +623,25 @@ tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, wlan_objmgr_ref_dbgid dbg_id) { + uint32_t vdev_id; + if (policy_mgr_get_connection_count(psoc) > 1) return NULL; - if (policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - dbg_id); - if (policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_CLIENT_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_P2P_CLIENT_MODE, - dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + return NULL; } @@ -705,10 +710,9 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, uint32_t tdls_feature_flags; QDF_STATUS status; - - /* If TDLS support is disabled then no need to update target */ - if (tdls_soc_obj->tdls_current_mode <= TDLS_SUPPORT_SUSPENDED) { - tdls_err("TDLS not enabled or suspended"); + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("TDLS mode is not enabled"); return; } @@ -717,23 +721,28 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, return; } - tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; - /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ - if (tdls_prohibited) { - tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; - } else { - tdls_debug("TDLS feature flags from ini %d ", + if (sta_connect_event) { + if (tdls_prohibited) { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; + } else { + tdls_debug("TDLS feature flags from ini %d ", tdls_feature_flags); - if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXP_TRIG_ONLY; - else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXT_CONTROL; - else - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_IMP_MODE; + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXT_CONTROL; + else + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_IMP_MODE; + } + } else { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; } tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); @@ -827,8 +836,6 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, done: qdf_mem_free(tdls_info_to_fw); - tdls_process_session_update(tdls_soc_obj->soc, - TDLS_CMD_SESSION_INCREMENT); return; } @@ -846,6 +853,11 @@ tdls_process_sta_connect(struct tdls_sta_notify_params *notify) tdls_debug("Check and update TDLS state"); + if (policy_mgr_get_connection_count(tdls_soc_obj->soc) > 1) { + tdls_debug("Concurrent sessions exist, TDLS can't be enabled"); + return QDF_STATUS_SUCCESS; + } + /* Association event */ if (!tdls_soc_obj->tdls_disable_in_progress) { tdls_send_update_to_fw(tdls_vdev_obj, @@ -872,8 +884,10 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_connect(notify); @@ -956,8 +970,10 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_disconnect(notify); @@ -968,6 +984,26 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return status; } +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id) +{ + struct tdls_sta_notify_params *notify; + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) { + tdls_err("memory allocation failed !!!"); + return; + } + + notify->lfr_roam = true; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->session_id = session_id; + notify->vdev = vdev; + + tdls_notify_sta_disconnect(notify); +} + /** * tdls_set_mode_in_vdev() - set TDLS mode * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b250c4d3d8..a518ceaa7a 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -583,6 +583,20 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); +/** + * tdls_peers_deleted_notification() - peer delete notification + * @vdev: vdev object + * @session_id: session 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. + * state. + * + * Return: None + */ +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id); + /** * tdls_notify_decrement_session() - Notify the session decrement * @psoc: psoc object manager diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 4357241a4e..4b1e99c4a3 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -146,4 +146,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type); +/** + * tgt_tdls_peers_deleted_notification()- notification from legacy lim + * @psoc: soc object + * @session_id: session id + * + * This function called from legacy lim to notify tdls peer deletion + * + * Return: None + */ +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index cd097dbf86..c292ac1fea 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -334,3 +334,24 @@ release_nbuf: return status; } +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id) +{ + struct wlan_objmgr_vdev *vdev; + + 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; + } + + tdls_peers_deleted_notification(vdev, session_id); + + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_SB_ID); +} + diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 427c183ae4..9bb85352bc 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -623,6 +623,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_chan_swit_prohibited = false; notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; + notify->lfr_roam = notify_info->lfr_roam; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 77776fed8b146276a74904ca3752b00cf38dc58e Mon Sep 17 00:00:00 2001 From: Vivek Date: Fri, 23 Jun 2017 21:05:31 +0530 Subject: [PATCH 19/89] qcacmn: Remove psoc/pdev locks for trivial APIs Remove psoc/pdev locks from trivial API's. This follows the changes from which the lock requirement from few simple APIs are removed. Change-Id: Ib5769c2234c8d57f485c0eef5a4e3c61fa170508 CRs-Fixed: 2060880 --- core/src/wlan_tdls_main.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index a518ceaa7a..0f699f319c 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -383,11 +383,9 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_psoc_obj_lock(psoc); soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - wlan_psoc_obj_unlock(psoc); return soc_obj; } @@ -406,11 +404,9 @@ wlan_psoc_get_tdls_soc_obj(struct wlan_objmgr_psoc *psoc) tdls_err("NULL psoc"); return NULL; } - wlan_psoc_obj_lock(psoc); soc_obj = (struct tdls_soc_priv_obj *) wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); - wlan_psoc_obj_unlock(psoc); return soc_obj; } From de1e5bcaa9741d3f5aa8d8b2bbc5461907f80712 Mon Sep 17 00:00:00 2001 From: Vivek Date: Wed, 21 Jun 2017 08:21:58 +0530 Subject: [PATCH 20/89] qcacmn: Remove vdev/peer locks for trivial APIs Remove vdev/peer locks from trivial API's. This follows the changes from which the lock requirement from few simple APIs are removed. Change-Id: I9972d51dfd1a42bdedbfd0fd4e67af03d030a1f5 CRs-Fixed: 2060880 --- core/src/wlan_tdls_cmds_process.c | 22 +--------------------- core/src/wlan_tdls_ct.c | 8 -------- core/src/wlan_tdls_main.c | 2 -- core/src/wlan_tdls_main.h | 4 ---- core/src/wlan_tdls_peer.c | 6 ------ dispatcher/src/wlan_tdls_tgt_api.c | 6 ------ 6 files changed, 1 insertion(+), 47 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 80a7ef3873..671eaf03c0 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -142,16 +142,13 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) addstareq->tdls_oper = TDLS_OPER_ADD; addstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); addstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -210,16 +207,13 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) delstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); delstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -281,16 +275,13 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) addstareq->tdls_oper = TDLS_OPER_UPDATE; addstareq->transaction_id = 0; - wlan_vdev_obj_lock(vdev); addstareq->session_id = wlan_vdev_get_id(vdev); peer = wlan_vdev_get_bsspeer(vdev); if (!peer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); status = QDF_STATUS_E_INVAL; goto error; } - wlan_vdev_obj_unlock(vdev); status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get bss peer"); @@ -1477,9 +1468,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); - wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( @@ -1573,14 +1562,13 @@ tdls_update_uapsd(struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_vdev *vdev, tdls_debug("No need to configure auto trigger:psb is 0"); return QDF_STATUS_SUCCESS; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); bsspeer = wlan_vdev_get_bsspeer(vdev); if (!bsspeer) { - wlan_vdev_obj_unlock(vdev); tdls_err("bss peer is NULL"); return QDF_STATUS_E_FAILURE; } + wlan_vdev_obj_lock(vdev); qdf_mem_copy(macaddr, wlan_peer_get_macaddr(bsspeer), QDF_MAC_ADDR_SIZE); wlan_vdev_obj_unlock(vdev); @@ -1663,9 +1651,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) tdls_set_peer_link_status(peer, TDLS_LINK_CONNECTED, TDLS_LINK_SUCCESS); - wlan_vdev_obj_lock(vdev); id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, id, mac, peer->sta_id, peer->signature, peer->qos); @@ -1744,9 +1730,7 @@ static QDF_STATUS tdls_config_force_peer( QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; - wlan_vdev_obj_lock(vdev); pdev = wlan_vdev_get_pdev(vdev); - wlan_vdev_obj_unlock(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!pdev || !vdev_obj || !soc_obj) { @@ -1784,9 +1768,7 @@ static QDF_STATUS tdls_config_force_peer( /* Update the peer mac to firmware, so firmware could update the * connection table */ - wlan_vdev_obj_lock(vdev); peer_update_param->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(peer_update_param->peer_macaddr, macaddr, QDF_MAC_ADDR_SIZE); peer_update_param->peer_state = TDLS_PEER_ADD_MAC_ADDR; @@ -1951,9 +1933,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) goto error; } - wlan_vdev_obj_lock(vdev); peer_update_param->vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); qdf_mem_copy(peer_update_param->peer_macaddr, macaddr, QDF_MAC_ADDR_SIZE); peer_update_param->peer_state = TDLS_PEER_REMOVE_MAC_ADDR; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d6e73f6974..1ed20b976f 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -32,18 +32,14 @@ bool tdls_is_vdev_connected(struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_peer *peer; enum wlan_peer_state peer_state; - wlan_vdev_obj_lock(vdev); peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); if (!peer) { tdls_err("peer is null"); return false; } - wlan_peer_obj_lock(peer); peer_state = wlan_peer_mlme_get_state(peer); - wlan_peer_obj_unlock(peer); if (peer_state != WLAN_ASSOC_STATE) { tdls_err("peer state: %d", peer_state); @@ -58,18 +54,14 @@ bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev) struct wlan_objmgr_peer *peer; bool is_authenticated = false; - wlan_vdev_obj_lock(vdev); peer = wlan_vdev_get_bsspeer(vdev); - wlan_vdev_obj_unlock(vdev); if (!peer) { tdls_err("peer is null"); return false; } - wlan_peer_obj_lock(peer); is_authenticated = wlan_peer_mlme_get_auth_state(peer); - wlan_peer_obj_unlock(peer); return is_authenticated; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 437b51f5fc..5ce0596f0e 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -430,9 +430,7 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, if (NULL == (*tdls_soc_obj)) return QDF_STATUS_E_FAILURE; - wlan_vdev_obj_lock(vdev); device_mode = wlan_vdev_mlme_get_opmode(vdev); - wlan_vdev_obj_unlock(vdev); if (device_mode != QDF_STA_MODE && device_mode != QDF_P2P_CLIENT_MODE) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 0f699f319c..f9f657a605 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -375,9 +375,7 @@ wlan_vdev_get_tdls_soc_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_vdev_obj_lock(vdev); psoc = wlan_vdev_get_psoc(vdev); - wlan_vdev_obj_unlock(vdev); if (!psoc) { tdls_err("can't get psoc"); return NULL; @@ -427,11 +425,9 @@ wlan_vdev_get_tdls_vdev_obj(struct wlan_objmgr_vdev *vdev) return NULL; } - wlan_vdev_obj_lock(vdev); vdev_obj = (struct tdls_vdev_priv_obj *) wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); - wlan_vdev_obj_unlock(vdev); return vdev_obj; } diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 56e5ec715e..c78f0f0f35 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -315,9 +315,7 @@ struct tdls_peer *tdls_is_progress(struct tdls_vdev_priv_obj *vdev_obj, return NULL; } - wlan_vdev_obj_lock(vdev_obj->vdev); psoc = wlan_vdev_get_psoc(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); if (!psoc) { tdls_err("invalid psoc"); return NULL; @@ -395,10 +393,8 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, if (!(TDLS_IS_OFF_CHANNEL_ENABLED( soc_obj->tdls_configs.tdls_feature_flags)) || soc_obj->tdls_fw_off_chan_mode != ENABLE_CHANSWITCH) { - wlan_vdev_obj_lock(vdev_obj->vdev); vdev_id = wlan_vdev_get_id(vdev_obj->vdev); opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); *channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); @@ -482,9 +478,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, } qdf_mem_zero(peer_param, sizeof(*peer_param)); - wlan_vdev_obj_lock(vdev_obj->vdev); peer_param->vdev_id = wlan_vdev_get_id(vdev_obj->vdev); - wlan_vdev_obj_unlock(vdev_obj->vdev); qdf_mem_copy(peer_param->peer_macaddr, peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index c292ac1fea..e1ab734fcc 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -244,21 +244,15 @@ QDF_STATUS tgt_tdls_mgmt_frame_process_rx_cb( tdls_err("current tdls vdev is null, can't get vdev id"); return QDF_STATUS_E_FAILURE; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_SB_ID); } else { - wlan_peer_obj_lock(peer); vdev = wlan_peer_get_vdev(peer); - wlan_peer_obj_unlock(peer); if (!vdev) { tdls_err("vdev is NULL in peer, drop this frame"); return QDF_STATUS_E_FAILURE; } - wlan_vdev_obj_lock(vdev); vdev_id = wlan_vdev_get_id(vdev); - wlan_vdev_obj_unlock(vdev); } rx_mgmt_event = qdf_mem_malloc(sizeof(*rx_mgmt_event)); From 52eb3c761df978e4499102f116945c1b70db7be8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 6 Jun 2017 19:40:03 -0700 Subject: [PATCH 21/89] qcacmn: Restructure TDLS function to fix the compilation issue When TDLS disabled at the build level, it triggers build failures in some of the projects, which does not support TDLS feature. Restructure the TDLS function to avoid build failures, when TDLS is not enabled. Change-Id: I3b63546f22d0187fb42d400fd7e15ff7a3d64653 CRs-Fixed: 2056022 --- core/src/wlan_tdls_main.c | 28 +++++++++++++++++++++++ core/src/wlan_tdls_main.h | 10 ++++++++ dispatcher/inc/wlan_tdls_public_structs.h | 10 ++++++++ dispatcher/inc/wlan_tdls_ucfg_api.h | 8 +++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 17 ++++++++++++++ 5 files changed, 73 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 5ce0596f0e..b894ba7d0d 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -290,6 +290,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_TEARDOWN_LINKS: tdls_teardown_connections(msg->bodyptr); break; + case TDLS_NOTIFY_RESET_ADAPTERS: + tdls_notify_reset_adapter(msg->bodyptr); + break; default: break; } @@ -982,6 +985,31 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return status; } +static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + struct tdls_vdev_priv_obj *tdls_vdev; + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!tdls_vdev) + return; + tdls_timers_stop(tdls_vdev); +} + +void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + QDF_ASSERT(0); + return; + } + + if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(vdev, + WLAN_TDLS_NB_ID)) + return; + + tdls_process_reset_adapter(vdev); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, uint32_t session_id) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index f9f657a605..58aa9cd2eb 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -575,6 +575,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); +/** + * tdls_notify_reset_adapter() - notify reset adapter + * @vdev: vdev object manager + * + * Notify TDLS about the adapter reset + * + * Return: None + */ +void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); + /** * tdls_peers_deleted_notification() - peer delete notification * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 974fca313b..4691869ffa 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -172,6 +172,15 @@ enum tdls_feature_mode { * @TDLS_CMD_REMOVE_FORCE_PEER: remove external peer * @TDLS_CMD_STATS_UPDATE: update tdls stats * @TDLS_CMD_CONFIG_UPDATE: config tdls + * @TDLS_CMD_SCAN_DONE: scon done event + * @TDLS_CMD_SET_RESPONDER: responder event + * @TDLS_NOTIFY_STA_CONNECTION: notify sta connection + * @TDLS_NOTIFY_STA_DISCONNECTION: notify sta disconnection + * @TDLS_CMD_SET_TDLS_MODE: set the tdls mode + * @TDLS_CMD_SESSION_INCREMENT: notify session increment + * @TDLS_CMD_SESSION_DECREMENT: notify session decrement + * @TDLS_CMD_TEARDOWN_LINKS: notify teardown + * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -191,6 +200,7 @@ enum tdls_command_type { TDLS_CMD_SESSION_INCREMENT, TDLS_CMD_SESSION_DECREMENT, TDLS_CMD_TEARDOWN_LINKS, + TDLS_NOTIFY_RESET_ADAPTERS, }; /** diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 5d99669740..0a06658fe8 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -146,6 +146,14 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); */ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev); +/** + * ucfg_tdls_notify_reset_adapter() - notify reset adapter + * @vdev: vdev object manager + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); + /** * ucfg_tdls_notify_sta_connect() - notify sta connect * @notify_info: sta notification info diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 9bb85352bc..67517aabc3 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -569,6 +569,23 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) return status; } +QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0, }; + + if (!vdev) { + tdls_err("vdev is NULL "); + return QDF_STATUS_E_NULL_VALUE; + } + tdls_debug("Enter "); + msg.bodyptr = vdev; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_RESET_ADAPTERS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + return status; +} + QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify_info) { From cccf099982a646fefa72f9c85e1ea26a17e12c7e Mon Sep 17 00:00:00 2001 From: Varun Reddy Yeturu Date: Thu, 10 Aug 2017 13:37:08 -0700 Subject: [PATCH 22/89] qcacmn: Add vdev as argument to wlan_serialization_comp_info_cb Add an additional argument to wlan_serialization_comp_info_cb to pass the vdev information while filling the information required to apply the rules. Change-Id: I44dadc01108e746fd2ce6353a90cdf9401dd6d06 CRs-Fixed: 2090987 --- core/src/wlan_tdls_main.c | 2 +- core/src/wlan_tdls_main.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b894ba7d0d..fc16026556 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1332,7 +1332,7 @@ return_success: return status; } -void tdls_scan_serialization_comp_info_cb( +void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, union wlan_serialization_rules_info *comp_info) { struct tdls_soc_priv_obj *tdls_soc; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 58aa9cd2eb..bfdcb2cb12 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -681,12 +681,13 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc); /** * tdls_scan_serialization_comp_info_cb() - callback for scan start + * @vdev: VDEV on which the scan command is being processed * @comp_info: serialize rules info * * Return: negative = caller should stop and return error code immediately * 1 = caller can continue to scan */ -void tdls_scan_serialization_comp_info_cb( +void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, union wlan_serialization_rules_info *comp_info); /** From a75fa9d06ad6f910d8989e413966031e5fb25650 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 23 Aug 2017 18:06:30 -0700 Subject: [PATCH 23/89] qcacmn: Fix TDLS peer capability initialization In tdls_set_peer_caps(), is_buffer_sta and is_off_channel_supported are declared, but are not initialized. This will create unpredictable problem in TDLS operations. Initialize all the variables with default values in peer capability. Change-Id: I469d7a56e1222944f3cd76efb76544aba7d8dff6 CRs-Fixed: 2092034 --- core/src/wlan_tdls_peer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index c78f0f0f35..1513295db4 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -618,7 +618,9 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, struct tdls_update_peer_params *req_info) { - uint8_t is_buffer_sta, is_off_channel_supported, is_qos_wmm_sta; + uint8_t is_buffer_sta = 0; + uint8_t is_off_channel_supported = 0; + uint8_t is_qos_wmm_sta = 0; struct tdls_soc_priv_obj *soc_obj; struct tdls_peer *curr_peer; uint32_t feature; @@ -643,7 +645,7 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, is_off_channel_supported = 1; if (TDLS_IS_WMM_ENABLED(feature) && req_info->is_qos_wmm_sta) - is_qos_wmm_sta = true; + is_qos_wmm_sta = 1; curr_peer->uapsd_queues = req_info->uapsd_queues; curr_peer->max_sp = req_info->max_sp; From 6ada3cdac934c7c9280b60b78d936ba69a968140 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 18 Sep 2017 10:07:54 -0700 Subject: [PATCH 24/89] qcacmn: umac: Replace instances of unadorned %p Replace instances of unadorned %p in umac. Change-Id: I7ae33c51405b31df24670dee3c98b6b4f1da9ab4 CRs-Fixed: 2111274 --- core/src/wlan_tdls_cmds_process.c | 56 ++++++++++++++--------------- core/src/wlan_tdls_ct.c | 2 +- core/src/wlan_tdls_main.c | 8 ++--- core/src/wlan_tdls_mgmt.c | 6 ++-- core/src/wlan_tdls_peer.c | 2 +- dispatcher/src/wlan_tdls_tgt_api.c | 18 +++++----- dispatcher/src/wlan_tdls_ucfg_api.c | 22 ++++++------ 7 files changed, 57 insertions(+), 57 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 671eaf03c0..5b66567618 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -338,7 +338,7 @@ tdls_internal_add_peer_rsp(struct tdls_add_peer_request *req, QDF_STATUS ret; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -370,7 +370,7 @@ tdls_internal_update_peer_rsp(struct tdls_update_peer_request *req, QDF_STATUS ret; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -400,7 +400,7 @@ static QDF_STATUS tdls_internal_del_peer_rsp(struct tdls_oper_request *req) QDF_STATUS status; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); return QDF_STATUS_E_INVAL; } vdev = req->vdev; @@ -442,7 +442,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); return QDF_STATUS_E_INVAL; } status = tdls_validate_current_mode(soc_obj); @@ -516,12 +516,12 @@ tdls_add_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -806,7 +806,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; goto error; } @@ -822,7 +822,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.vdev = vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -880,7 +880,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); return QDF_STATUS_E_INVAL; } @@ -960,12 +960,12 @@ tdls_update_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -1014,7 +1014,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_FAILURE; goto error; } @@ -1031,7 +1031,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.vdev = req->vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -1084,12 +1084,12 @@ tdls_del_peer_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("cmd: %p, reason: %d", cmd, reason); + tdls_err("cmd: %pK, reason: %d", cmd, reason); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; - tdls_debug("reason: %d, req %p", reason, req); + tdls_debug("reason: %d, req %pK", reason, req); switch (reason) { case WLAN_SER_CB_ACTIVATE_CMD: @@ -1136,7 +1136,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { - tdls_err("req: %p", req); + tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; goto error; } @@ -1152,7 +1152,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.vdev = vdev; ser_cmd_status = wlan_serialization_request(&cmd); - tdls_debug("req: 0x%p wlan_serialization_request status:%d", req, + tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, ser_cmd_status); switch (ser_cmd_status) { @@ -1256,7 +1256,7 @@ QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); if (!tdls_soc || !tdls_vdev) { - tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); status = QDF_STATUS_E_FAILURE; } @@ -1311,7 +1311,7 @@ QDF_STATUS tdls_send_mgmt_tx_completion( tdls_vdev = wlan_vdev_get_tdls_vdev_obj(vdev); if (!tdls_soc || !tdls_vdev) { - tdls_err("soc object:%p, vdev object:%p", tdls_soc, tdls_vdev); + tdls_err("soc object:%pK, vdev object:%pK", tdls_soc, tdls_vdev); status = QDF_STATUS_E_FAILURE; } @@ -1356,7 +1356,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); status = QDF_STATUS_E_FAILURE; goto cmddone; } @@ -1449,7 +1449,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc object:%p, vdev object:%p", soc_obj, vdev_obj); + tdls_err("soc object:%pK, vdev object:%pK", soc_obj, vdev_obj); status = QDF_STATUS_E_FAILURE; goto cmddone; } @@ -1622,7 +1622,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!vdev_obj || !soc_obj) { - tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); status = QDF_STATUS_E_NULL_VALUE; goto error; } @@ -1734,7 +1734,7 @@ static QDF_STATUS tdls_config_force_peer( vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!pdev || !vdev_obj || !soc_obj) { - tdls_err("pdev: %p, vdev_obj: %p, soc_obj: %p", + tdls_err("pdev: %pK, vdev_obj: %pK, soc_obj: %pK", pdev, vdev_obj, soc_obj); return QDF_STATUS_E_INVAL; } @@ -1876,7 +1876,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) vdev_obj = wlan_vdev_get_tdls_vdev_obj(req->vdev); soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p", soc_obj, vdev_obj); + tdls_err("soc_obj: %pK, vdev_obj: %pK", soc_obj, vdev_obj); status = QDF_STATUS_E_INVAL; goto error; } @@ -1988,7 +1988,7 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2045,7 +2045,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2090,7 +2090,7 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); if (!soc_obj || !vdev_obj) { - tdls_err("soc_obj: %p, vdev_obj: %p, ignore %s", + tdls_err("soc_obj: %pK, vdev_obj: %pK, ignore %s", soc_obj, vdev_obj, tdls_evt_to_str(type)); return QDF_STATUS_E_NULL_VALUE; } @@ -2138,7 +2138,7 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req) QDF_STATUS status; if (!set_req || !set_req->vdev) { - tdls_err("Invalid input params %p", set_req); + tdls_err("Invalid input params %pK", set_req); return -EINVAL; } diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 1ed20b976f..a07f6dc418 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -515,7 +515,7 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); if (!tdls_soc || !tdls_vdev || !curr_peer) { - tdls_err("tdls_soc: %p, tdls_vdev: %p, curr_peer: %p", + tdls_err("tdls_soc: %pK, tdls_vdev: %pK, curr_peer: %pK", tdls_soc, tdls_vdev, curr_peer); return; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index fc16026556..b66edc02cd 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -236,7 +236,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%p", msg); + tdls_err("msg: 0x%pK", msg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -307,7 +307,7 @@ QDF_STATUS tdls_process_evt(struct scheduler_msg *msg) struct tdls_event_info *event; if (!msg || !msg->bodyptr) { - tdls_err("msg is not valid: %p", msg); + tdls_err("msg is not valid: %pK", msg); return QDF_STATUS_E_NULL_VALUE; } notify = msg->bodyptr; @@ -602,7 +602,7 @@ QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) { if (!psoc) { - tdls_err("psoc: %p", psoc); + tdls_err("psoc: %pK", psoc); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("enter "); @@ -1252,7 +1252,7 @@ static QDF_STATUS tdls_post_scan_done_msg(struct tdls_soc_priv_obj *tdls_soc) struct scheduler_msg msg = {0, }; if (!tdls_soc) { - tdls_err("tdls_soc: %p ", tdls_soc); + tdls_err("tdls_soc: %pK ", tdls_soc); return QDF_STATUS_E_NULL_VALUE; } diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 2bef1af535..d0bbf33269 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -98,7 +98,7 @@ static QDF_STATUS tdls_process_rx_mgmt( return QDF_STATUS_E_INVAL; } - tdls_debug("soc:%p, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%p", + tdls_debug("soc:%pK, frame_len:%d, rx_chan:%d, vdev_id:%d, frm_type:%d, rx_rssi:%d, buf:%pK", tdls_soc_obj->soc, rx_mgmt->frame_len, rx_mgmt->rx_chan, rx_mgmt->vdev_id, rx_mgmt->frm_type, rx_mgmt->rx_rssi, rx_mgmt->buf); @@ -176,7 +176,7 @@ QDF_STATUS tdls_mgmt_rx_ops(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; int num_of_entries; - tdls_debug("psoc:%p, is register rx:%d", psoc, isregister); + tdls_debug("psoc:%pK, is register rx:%d", psoc, isregister); frm_cb_info.frm_type = MGMT_ACTION_TDLS_DISCRESP; frm_cb_info.mgmt_rx_cb = tgt_tdls_mgmt_frame_rx_cb; @@ -321,7 +321,7 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, QDF_STATUS status = QDF_STATUS_SUCCESS; if (!cmd || !cmd->umac_cmd) { - tdls_err("invalid params cmd: %p, ", cmd); + tdls_err("invalid params cmd: %pK, ", cmd); return QDF_STATUS_E_NULL_VALUE; } req = cmd->umac_cmd; diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 1513295db4..26837ffdd8 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -473,7 +473,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev); pdev = wlan_vdev_get_pdev(vdev_obj->vdev); if (!soc_obj || !pdev) { - tdls_err("soc_obj: %p, pdev: %p", soc_obj, pdev); + tdls_err("soc_obj: %pK, pdev: %pK", soc_obj, pdev); return; } diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index e1ab734fcc..4100c29ad6 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -92,7 +92,7 @@ QDF_STATUS tgt_tdls_send_mgmt_tx_completion(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -107,7 +107,7 @@ QDF_STATUS tgt_tdls_send_mgmt_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -122,7 +122,7 @@ QDF_STATUS tgt_tdls_add_peer_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -137,7 +137,7 @@ QDF_STATUS tgt_tdls_del_peer_rsp(struct scheduler_msg *pmsg) QDF_STATUS status = QDF_STATUS_SUCCESS; if (!pmsg || !pmsg->bodyptr) { - tdls_err("msg: 0x%p", pmsg); + tdls_err("msg: 0x%pK", pmsg); QDF_ASSERT(0); return QDF_STATUS_E_NULL_VALUE; } @@ -179,7 +179,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, QDF_STATUS status; if (!psoc || !info) { - tdls_err("psoc: 0x%p, info: 0x%p", psoc, info); + tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, @@ -196,7 +196,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_TDLS_SB_ID); if (!notify->vdev) { - tdls_err("null vdev, vdev_id: %d, psoc: 0x%p", vdev_id, psoc); + tdls_err("null vdev, vdev_id: %d, psoc: 0x%pK", vdev_id, psoc); return QDF_STATUS_E_INVAL; } qdf_mem_copy(¬ify->event, info, sizeof(*info)); @@ -298,16 +298,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb( { QDF_STATUS status; - tdls_debug("psoc:%p, peer:%p, type:%d", psoc, peer, frm_type); + tdls_debug("psoc:%pK, peer:%pK, type:%d", psoc, peer, frm_type); if (!buf) { - tdls_err("rx frame buff is null buf:%p", buf); + tdls_err("rx frame buff is null buf:%pK", buf); return QDF_STATUS_E_INVAL; } if (!mgmt_rx_params || !psoc) { - tdls_err("input is NULL mgmt_rx_params:%p psoc:%p, peer:%p", + tdls_err("input is NULL mgmt_rx_params:%pK psoc:%pK, peer:%pK", mgmt_rx_params, psoc, peer); status = QDF_STATUS_E_INVAL; goto release_nbuf; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 67517aabc3..5b41921a02 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -183,7 +183,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, tdls_notice("tdls update config "); if (!psoc || !req) { - tdls_err("psoc: 0x%p, req: 0x%p", psoc, req); + tdls_err("psoc: 0x%pK, req: 0x%pK", psoc, req); return QDF_STATUS_E_FAILURE; } @@ -248,7 +248,7 @@ QDF_STATUS ucfg_tdls_psoc_enable(struct wlan_objmgr_psoc *psoc) { QDF_STATUS status; - tdls_notice("psoc tdls enable: 0x%p", psoc); + tdls_notice("psoc tdls enable: 0x%pK", psoc); if (!psoc) { tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; @@ -281,7 +281,7 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj = NULL; - tdls_notice("psoc tdls disable: 0x%p", psoc); + tdls_notice("psoc tdls disable: 0x%pK", psoc); if (!psoc) { tdls_err("NULL psoc"); return QDF_STATUS_E_FAILURE; @@ -337,7 +337,7 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !add_peer_req) { - tdls_err("vdev: %p, req %p", vdev, add_peer_req); + tdls_err("vdev: %pK, req %pK", vdev, add_peer_req); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("vdevid: %d, peertype: %d", @@ -383,7 +383,7 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !update_peer) { - tdls_err("vdev: %p, update_peer: %p", vdev, update_peer); + tdls_err("vdev: %pK, update_peer: %pK", vdev, update_peer); return QDF_STATUS_E_NULL_VALUE; } @@ -443,7 +443,7 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; if (!vdev || !macaddr) { - tdls_err("vdev: %p, mac %p", vdev, macaddr); + tdls_err("vdev: %pK, mac %pK", vdev, macaddr); return QDF_STATUS_E_NULL_VALUE; } @@ -490,7 +490,7 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *mgmt_req; if (!req || !req->vdev) { - tdls_err("Invalid mgmt req params %p", req); + tdls_err("Invalid mgmt req params %pK", req); return QDF_STATUS_E_NULL_VALUE; } @@ -529,7 +529,7 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) QDF_STATUS status; if (!req || !req->vdev) { - tdls_err("invalid input %p", req); + tdls_err("invalid input %pK", req); return QDF_STATUS_E_NULL_VALUE; } @@ -593,7 +593,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %p, notify_info %p", + tdls_err("notify_info->vdev: %pK, notify_info %pK", notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -625,7 +625,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %p, notify_info %p", + tdls_err("notify_info->vdev: %pK, notify_info %pK", notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -659,7 +659,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( struct tdls_set_mode_params *set_mode; if (!set_mode_params || !set_mode_params->vdev) { - tdls_err("vdev: %p, set_mode_params %p", + tdls_err("vdev: %pK, set_mode_params %pK", set_mode_params->vdev, set_mode_params); return QDF_STATUS_E_NULL_VALUE; } From c441d7b5a8beb3bb718b447c1b38ff5ea6144752 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 7 Sep 2017 20:06:17 -0700 Subject: [PATCH 25/89] qcacmn: Add host data path functions for TDLS Add and enable host data path functions for Napier TDLS. Change-Id: I228c2dcf4e8d797d173007a3306d112aca5ba52f CRs-Fixed: 2114813 --- core/src/wlan_tdls_cmds_process.c | 35 +++++++++++++++++++++++++++-- core/src/wlan_tdls_ct.c | 3 +-- dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 5b66567618..3b9f1ad339 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1133,6 +1133,10 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) struct wlan_serialization_command cmd = {0,}; enum wlan_serialization_status ser_cmd_status; struct wlan_objmgr_vdev *vdev; + struct tdls_vdev_priv_obj *vdev_obj; + struct tdls_soc_priv_obj *soc_obj; + uint8_t *mac; + struct tdls_peer *peer; QDF_STATUS status = QDF_STATUS_SUCCESS; if (!req || !req->vdev) { @@ -1140,7 +1144,35 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) status = QDF_STATUS_E_INVAL; goto error; } + vdev = req->vdev; + + /* vdev reference cnt is acquired in ucfg_tdls_oper */ + vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + + if (!vdev_obj || !soc_obj) { + tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + status = QDF_STATUS_E_NULL_VALUE; + goto error; + } + + mac = req->peer_addr; + peer = tdls_find_peer(vdev_obj, mac); + if (!peer) { + tdls_err(QDF_MAC_ADDRESS_STR + " not found, ignore NL80211_TDLS_ENABLE_LINK", + QDF_MAC_ADDR_ARRAY(mac)); + status = QDF_STATUS_E_INVAL; + goto error; + } + + if (soc_obj->tdls_dp_vdev_update) + soc_obj->tdls_dp_vdev_update(&soc_obj->soc, + peer->sta_id, + soc_obj->tdls_update_dp_vdev_flags, + false); + cmd.cmd_type = WLAN_SER_CMD_TDLS_DEL_PEER; cmd.cmd_id = 0; cmd.cmd_cb = (wlan_serialization_cmd_callback) @@ -1904,8 +1936,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) soc_obj->tdls_dp_vdev_update(&soc_obj->soc, peer->sta_id, soc_obj->tdls_update_dp_vdev_flags, - ((peer->link_status == - TDLS_LINK_CONNECTED) ? true : false)); + false); if (soc_obj->tdls_event_cb) { qdf_mem_copy(ind.peer_mac, macaddr, QDF_MAC_ADDR_SIZE); diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index a07f6dc418..2b676114c8 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -532,8 +532,7 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc, curr_peer->sta_id, tdls_soc->tdls_update_dp_vdev_flags, - ((curr_peer->link_status == - TDLS_LINK_CONNECTED) ? true : false)); + false); indication.reason = reason; indication.vdev = tdls_vdev->vdev; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 5b41921a02..c5bf80475e 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -218,6 +218,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_update_peer_state = req->tdls_update_peer_state; soc_obj->tdls_del_all_peers = req->tdls_del_all_peers; soc_obj->tdls_update_dp_vdev_flags = req->tdls_update_dp_vdev_flags; + soc_obj->tdls_dp_vdev_update = req->tdls_dp_vdev_update; tdls_pm_call_backs.tdls_notify_increment_session = tdls_notify_increment_session; From 51c7fdeb9ebc61f4a6b9d70f7adf418380009298 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 10 Oct 2017 01:36:39 -0700 Subject: [PATCH 26/89] qcacmn: Fix TDLS set state cmd sequence in concurrent TDLS connections TDLS set state cmd to firmware is going out of sequence, if STA is disconnected, when concurrent TDLS connections are active. This out of sequence causes crash in the firmware. Fix the out of sequence issue, by grouping all the TDLS delete peer commands into one single command. Change-Id: Idd315d544c46bcf063881bff5be70cb5d9ad0ea2 CRs-Fixed: 2123838 --- core/src/wlan_tdls_ct.c | 1 - core/src/wlan_tdls_ct.h | 12 ++++++++++++ core/src/wlan_tdls_main.c | 7 +++++++ dispatcher/inc/wlan_tdls_public_structs.h | 1 + dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2b676114c8..8010442839 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1157,7 +1157,6 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, * * Return: QDF_STATUS */ -static QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc) { diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 63e3063780..b713c971b4 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -194,4 +194,16 @@ void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev); void tdls_disable_offchan_and_teardown_links( struct wlan_objmgr_vdev *vdev); +/** + * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * @vdev: vdev object + * @tdls_soc: tdls soc object + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, + struct tdls_soc_priv_obj *tdls_soc); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index b66edc02cd..53de842078 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -915,6 +915,12 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) &tdls_soc_obj)) return QDF_STATUS_E_INVAL; + /* if the disconnect comes from user space, we have to delete all the + * tdls peers before sending the set state cmd. + */ + if (notify->user_disconnect) + return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj); + tdls_debug("Check and update TDLS state"); curr_tdls_vdev = tdls_vdev_obj; @@ -1026,6 +1032,7 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify->tdls_prohibited = false; notify->session_id = session_id; notify->vdev = vdev; + notify->user_disconnect = false; tdls_notify_sta_disconnect(notify); } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4691869ffa..eaed5612c7 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1012,6 +1012,7 @@ struct tdls_sta_notify_params { bool tdls_prohibited; bool tdls_chan_swit_prohibited; bool lfr_roam; + bool user_disconnect; uint8_t session_id; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c5bf80475e..0d8f34c56a 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -642,6 +642,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; notify->lfr_roam = notify_info->lfr_roam; + notify->user_disconnect = notify_info->user_disconnect; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 93225df9d163e4f88623ea88f8e3fe9dc632d6af Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 17 May 2017 14:03:37 +0800 Subject: [PATCH 27/89] qcacmn: Send TDLS frames with lower AC If ACM enabled and access is not granted for AC_VI, then send TDLS frames with lower access category instead of dropping them. Change-Id: I2201536dc4475764f33eebce1faa0a7df0b2c454 CRs-Fixed: 2119433 --- core/src/wlan_tdls_cmds_process.c | 24 ++++++++++------------- core/src/wlan_tdls_cmds_process.h | 10 +--------- core/src/wlan_tdls_main.h | 1 - core/src/wlan_tdls_mgmt.c | 6 +++++- core/src/wlan_tdls_mgmt.h | 1 + dispatcher/inc/wlan_tdls_public_structs.h | 1 + dispatcher/src/wlan_tdls_tgt_api.c | 1 + dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 8 files changed, 20 insertions(+), 25 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 3b9f1ad339..6f54b081b4 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -648,7 +648,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, return 0; } -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) +int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) { struct tdls_vdev_priv_obj *tdls_vdev; struct tdls_soc_priv_obj *tdls_soc; @@ -656,6 +656,8 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) struct tdls_peer *temp_peer; QDF_STATUS status; + struct tdls_validate_action_req *tdls_validate = + tdls_mgmt_req->chk_frame; if (!tdls_validate || !tdls_validate->vdev) return -EINVAL; @@ -711,21 +713,15 @@ int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate) } } - /* - * Discard TDLS Discovery request and setup confirm if violates - * ACM rules - */ - if ((TDLS_DISCOVERY_REQUEST == tdls_validate->action_code || - TDLS_SETUP_CONFIRM == tdls_validate->action_code)) { - /* call hdd_wmm_is_acm_allowed() */ - if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { - tdls_err("admission ctrl set to VI, action %d declined", - tdls_validate->action_code); - return -EPERM; - } + /* call hdd_wmm_is_acm_allowed() */ + if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d", + tdls_validate->action_code); + tdls_mgmt_req->use_default_ac = false; + } else { + tdls_mgmt_req->use_default_ac = true; } - if (TDLS_SETUP_REQUEST == tdls_validate->action_code || TDLS_SETUP_RESPONSE == tdls_validate->action_code) { if (tdls_soc->max_num_tdls_sta <= diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 5e2c035084..561a40d78b 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -286,14 +286,6 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, int tdls_set_cap(struct tdls_vdev_priv_obj *tdls_vdev, const uint8_t *mac, enum tdls_peer_capab cap); -/** - * tdls_validate_mgmt_request() -validate mgmt request - * @tdls_validate: action frame request - * - * Return: 0 for success or -EINVAL otherwise - */ -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); - /** * tdls_process_send_mgmt_rsp() - handle response for send mgmt * @rsp: TDLS send mgmt response @@ -355,7 +347,7 @@ QDF_STATUS tdls_process_connection_tracker_notify(struct wlan_objmgr_vdev *vdev, * * Return: 0 for success or -EINVAL otherwise */ -int tdls_validate_mgmt_request(struct tdls_validate_action_req *tdls_validate); +int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req); /** * tdls_set_responder() - Set/clear TDLS peer's responder role diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index bfdcb2cb12..95178af8cc 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -34,7 +34,6 @@ #include #include #include "wlan_serialization_api.h" -#include "wlan_tdls_mgmt.h" /* Bit mask flag for tdls_option to FW */ #define ENA_TDLS_OFFCHAN (1 << 0) /* TDLS Off Channel support */ diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index d0bbf33269..c7582196e8 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -291,6 +291,10 @@ static QDF_STATUS tdls_activate_send_mgmt_request( tdls_mgmt_req->length = sizeof(struct tdls_send_mgmt_request) + action_req->tdls_mgmt.len; + if (action_req->use_default_ac) + tdls_mgmt_req->ac = WIFI_AC_VI; + else + tdls_mgmt_req->ac = WIFI_AC_BK; /* Send the request to PE. */ qdf_mem_zero(&msg, sizeof(msg)); @@ -370,7 +374,7 @@ QDF_STATUS tdls_process_mgmt_req( enum wlan_serialization_status ser_cmd_status; /* If connected and in Infra. Only then allow this */ - status = tdls_validate_mgmt_request(tdls_mgmt_req->chk_frame); + status = tdls_validate_mgmt_request(tdls_mgmt_req); if (status != QDF_STATUS_SUCCESS) { status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, status); diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index 3d3e6dd54a..a6973f17d7 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -73,6 +73,7 @@ struct tdls_send_mgmt_request { uint32_t peer_capability; struct qdf_mac_addr bssid; struct qdf_mac_addr peer_mac; + enum wifi_traffic_ac ac; /* Variable length. Dont add any field after this. */ uint8_t add_ie[1]; }; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index eaed5612c7..712a81dac8 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -985,6 +985,7 @@ struct tdls_action_frame_request { const uint8_t *cmd_buf; uint8_t len; struct tdls_send_mgmt tdls_mgmt; + bool use_default_ac; }; /** diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 4100c29ad6..8b35247d8b 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -26,6 +26,7 @@ #include #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" +#include "../../core/src/wlan_tdls_mgmt.h" static inline struct wlan_lmac_if_tdls_tx_ops * wlan_psoc_get_tdls_txops(struct wlan_objmgr_psoc *psoc) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 0d8f34c56a..930ea1bf93 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -27,6 +27,7 @@ #include "../../core/src/wlan_tdls_main.h" #include "../../core/src/wlan_tdls_cmds_process.h" #include "../../core/src/wlan_tdls_ct.h" +#include "../../core/src/wlan_tdls_mgmt.h" #include #include #include "wlan_policy_mgr_api.h" From 17e4c635ca1a54702269019865dee5393dc4d026 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 1 Nov 2017 20:58:23 -0700 Subject: [PATCH 28/89] qcacmn: Fix the invalid memory access issue in TDLS Additional IE's in the TDLS management request is not populated correctly and it causes invalid memory access and system crash. Populate the additional TDLS IE's in correct order. Change-Id: I1c65f04c3b0e134dc4854e3f16022c887e8ce7c0 CRs-Fixed: 2136739 --- dispatcher/inc/wlan_tdls_public_structs.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 712a81dac8..936623c0eb 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -930,9 +930,8 @@ struct tdls_event_notify { * @dialog: dialog token used in the frame. * @status_code: status to be incuded in the frame * @responder: Tdls request type - * @len: lenght of additional Ies * @peer_capability: peer cpabilities - * @len: lenght of additional Ies + * @len: length of additional Ies * @buf: additional IEs to be included */ struct tdls_send_mgmt { @@ -944,7 +943,7 @@ struct tdls_send_mgmt { uint32_t peer_capability; uint8_t len; /* Variable length, do not add anything after this */ - uint8_t *buf; + uint8_t buf[]; }; /** @@ -975,6 +974,9 @@ struct tdls_validate_action_req { * @chk_frame: frame validation structure * @session_id: session id * @vdev_id: vdev id + * @cmd_buf: cmd buffer + * @len: length of the frame + * @use_default_ac: access category * @tdls_mgmt: tdls managment */ struct tdls_action_frame_request { @@ -984,8 +986,9 @@ struct tdls_action_frame_request { uint8_t vdev_id; const uint8_t *cmd_buf; uint8_t len; - struct tdls_send_mgmt tdls_mgmt; bool use_default_ac; + /* Variable length, do not add anything after this */ + struct tdls_send_mgmt tdls_mgmt; }; /** From 198678568916f21b1aeee9ce93adcf9e2d9d7b9b Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 9 Nov 2017 09:54:12 -0800 Subject: [PATCH 29/89] qcacmn: Use enum QDF_OPMODE Change "qcacmn: Rename enum tQDF_ADAPTER_MODE" (qca-wifi-host-cmn Change-Id I20f1b6d1a0ab4b8fe6a85cefdff96a49e2f4652c) renamed enum tQDF_ADAPTER_MODE to QDF_OPMODE. Update all references to use the new name. Change-Id: Ic6f663dac11a100f168b2626c7c0fbcaccbfca4f CRs-Fixed: 2141061 --- core/src/wlan_tdls_main.c | 4 ++-- core/src/wlan_tdls_peer.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 53de842078..000bc78ee1 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -420,7 +420,7 @@ QDF_STATUS tdls_get_vdev_objects(struct wlan_objmgr_vdev *vdev, struct tdls_vdev_priv_obj **tdls_vdev_obj, struct tdls_soc_priv_obj **tdls_soc_obj) { - enum tQDF_ADAPTER_MODE device_mode; + enum QDF_OPMODE device_mode; if (NULL == vdev) return QDF_STATUS_E_FAILURE; @@ -1275,7 +1275,7 @@ void tdls_scan_complete_event_handler(struct wlan_objmgr_vdev *vdev, struct scan_event *event, void *arg) { - enum tQDF_ADAPTER_MODE device_mode; + enum QDF_OPMODE device_mode; struct tdls_soc_priv_obj *tdls_soc; if (!vdev || !event || !arg) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 26837ffdd8..769ba53342 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -384,7 +384,7 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, uint32_t *channel, uint32_t *opclass) { uint32_t vdev_id; - enum tQDF_ADAPTER_MODE opmode; + enum QDF_OPMODE opmode; /* * If tdls offchannel is not enabled then we provide base channel * and in that case pass opclass as 0 since opclass is mainly needed From ce66489b627ccad46fe74eb3d2c197d105a3f91a Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Thu, 2 Nov 2017 17:24:10 -0700 Subject: [PATCH 30/89] qcacmn: tdls: Replace instances of unadorned %p Replace instances of unadorned %p in tdls. Change-Id: Ife7db6d669d04c7e2d8e1a6fec5b442e180a34bb CRs-Fixed: 2133327 --- core/src/wlan_tdls_cmds_process.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 6f54b081b4..6780f0a2c2 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1148,7 +1148,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); if (!vdev_obj || !soc_obj) { - tdls_err("tdls vdev_obj: %p soc_obj: %p", vdev_obj, soc_obj); + tdls_err("tdls vdev_obj: %pK soc_obj: %pK", vdev_obj, soc_obj); status = QDF_STATUS_E_NULL_VALUE; goto error; } From c993cb8078fc1431690bb72f22c62355c8665a89 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Wed, 8 Nov 2017 16:42:12 -0800 Subject: [PATCH 31/89] qcacmn: Fix memory leak issue in tdls peer delete operation In TDLS peer delete function memory is not freed in error handling path and it causes leak for every error operation. Free the memory in error handling path. Change-Id: Idb4725ec7a4c1b9614ecad1f685ffdeb8f795e72 CRs-Fixed: 2139570 --- core/src/wlan_tdls_ct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 8010442839..a7636e34b5 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1176,6 +1176,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, peer = wlan_vdev_get_bsspeer(vdev); if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID)) { + qdf_mem_free(del_msg); return QDF_STATUS_E_FAILURE; } From 4058ac5456e2d23cd5de38def88a18cd37a68afd Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 14 Nov 2017 17:19:29 -0800 Subject: [PATCH 32/89] qcacmn: Add TDLS user command getTDLSPeers Add TDLS user command getTDLSPeers for TDLS functional verification Change-Id: Ia02461a364ca604672d728f7dad7c3537e78f067 CRs-Fixed: 2146626 --- core/src/wlan_tdls_main.c | 94 +++++++++++++++++++++++ core/src/wlan_tdls_main.h | 10 +++ dispatcher/inc/wlan_tdls_public_structs.h | 20 +++++ dispatcher/inc/wlan_tdls_ucfg_api.h | 11 +++ dispatcher/src/wlan_tdls_ucfg_api.c | 29 +++++++ 5 files changed, 164 insertions(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 000bc78ee1..a423dcd08a 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -293,6 +293,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); break; + case TDLS_CMD_GET_ALL_PEERS: + tdls_get_all_peers_from_list(msg->bodyptr); + break; default: break; } @@ -1001,6 +1004,97 @@ static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_timers_stop(tdls_vdev); } +static int __tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int i; + int len, init_len; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + char *buf; + int buf_len; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + tdls_notice("Enter "); + + buf = get_tdls_peers->buf; + buf_len = get_tdls_peers->buf_len; + + if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { + len = qdf_scnprintf(buf, buf_len, + "\nSTA is not associated\n"); + return len; + } + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); + + if (!tdls_vdev) { + len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); + return len; + } + + init_len = buf_len; + len = qdf_scnprintf(buf, buf_len, + "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buf_len -= len; + len = qdf_scnprintf(buf, buf_len, + "---------------------------------\n"); + buf += len; + buf_len -= len; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, + struct tdls_peer, node); + if (buf_len < 32 + 1) + break; + len = qdf_scnprintf(buf, buf_len, + QDF_MAC_ADDRESS_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->sta_id, + (curr_peer->tdls_support == + TDLS_CAP_SUPPORTED) ? "Y" : "N", + TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : + "N", curr_peer->rssi); + buf += len; + buf_len -= len; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + tdls_notice("Exit "); + return init_len - buf_len; +} + +void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int32_t len; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!get_tdls_peers->vdev) + qdf_mem_free(get_tdls_peers); + + len = __tdls_get_all_peers_from_list(get_tdls_peers); + + indication.status = len; + indication.vdev = get_tdls_peers->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_USER_CMD, &indication); + + qdf_mem_free(get_tdls_peers); +} + void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) { if (!vdev) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 95178af8cc..0dee99c63f 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -574,6 +574,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); + +/** + * tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: None + */ +void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers); + /** * tdls_notify_reset_adapter() - notify reset adapter * @vdev: vdev object manager diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 936623c0eb..ae0a4077b2 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -62,6 +62,9 @@ /** Maximum time(ms) to wait for tdls mgmt to complete **/ #define WAIT_TIME_FOR_TDLS_MGMT 11000 +/** Maximum time(ms) to wait for tdls mgmt to complete **/ +#define WAIT_TIME_FOR_TDLS_USER_CMD 11000 + /** Maximum waittime for TDLS teardown links **/ #define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 @@ -181,6 +184,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SESSION_DECREMENT: notify session decrement * @TDLS_CMD_TEARDOWN_LINKS: notify teardown * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset + * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -201,6 +205,7 @@ enum tdls_command_type { TDLS_CMD_SESSION_DECREMENT, TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, + TDLS_CMD_GET_ALL_PEERS, }; /** @@ -213,6 +218,8 @@ enum tdls_command_type { * @TDLS_EVENT_DISCOVERY_REQ: dicovery request * @TDLS_EVENT_TEARDOWN_REQ: teardown request * @TDLS_EVENT_SETUP_REQ: setup request + * @TDLS_EVENT_TEARDOWN_LINKS_DONE: teardown completion event + * @TDLS_EVENT_USER_CMD: tdls user command */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -224,6 +231,7 @@ enum tdls_event_type { TDLS_EVENT_TEARDOWN_REQ, TDLS_EVENT_SETUP_REQ, TDLS_EVENT_TEARDOWN_LINKS_DONE, + TDLS_EVENT_USER_CMD, }; /** @@ -968,6 +976,18 @@ struct tdls_validate_action_req { int max_sta_failed; }; +/** + * struct tdls_get_all_peers - get all peers from the list + * @vdev: vdev object + * @buf: output string buffer to hold the peer info + * @buf_len: the size of output string buffer + */ +struct tdls_get_all_peers { + struct wlan_objmgr_vdev *vdev; + char *buf; + int buf_len; +}; + /** * struct tdls_send_action_frame_request - tdls send mgmt request * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 0a06658fe8..f23bf52aeb 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -119,6 +119,17 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, const uint8_t *macaddr, enum tdls_command_type cmd); +/** + * ucfg_tdls_get_all_peers() - get all tdls peers from the list + * @vdev: vdev object + * @buf: output buffer + * @buflen: length of written data + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen); + /** * ucfg_tdls_send_mgmt_frame() - send TDLS mgmt frame * @mgmt_req: pointer to TDLS action frame request struct diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 930ea1bf93..36c6318156 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -485,6 +485,35 @@ error: return status; } +QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, + char *buf, int buflen) +{ + struct scheduler_msg msg = {0, }; + struct tdls_get_all_peers *tdls_peers; + QDF_STATUS status; + + tdls_peers = qdf_mem_malloc(sizeof(*tdls_peers)); + + if (!tdls_peers) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + tdls_peers->vdev = vdev; + tdls_peers->buf_len = buflen; + tdls_peers->buf = buf; + + msg.bodyptr = tdls_peers; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_GET_ALL_PEERS; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + + if (status != QDF_STATUS_SUCCESS) + qdf_mem_free(tdls_peers); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { From 7fc7beb46328f3aabec9c5f3ef65883a1f692a75 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 21 Jul 2017 18:02:02 +0800 Subject: [PATCH 33/89] qcacmn: Dynamic antenna switch in TDLS operation Support dynamic antenna switch in TDLS: 1. If TDLS NSS is configured to be 1x1, TDLS connections not teardown; 2. When antenna mode switched from 2x2 to 1x1, TDLS connections teared down and EAGAIN returned; When antenna mode switched from 1x1 to 2x2, TDLS connections is still teardown, but success in one trial. Change-Id: I1877002122a96dc8f40c796f8a1b938199d3b67a CRs-Fixed: 2080461 --- core/src/wlan_tdls_cmds_process.c | 149 +++++++++++++++++++++- core/src/wlan_tdls_cmds_process.h | 20 +++ core/src/wlan_tdls_main.c | 2 + dispatcher/inc/wlan_tdls_public_structs.h | 20 +++ dispatcher/inc/wlan_tdls_ucfg_api.h | 10 ++ dispatcher/src/wlan_tdls_ucfg_api.c | 40 ++++++ 6 files changed, 240 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 6780f0a2c2..e934f4f49a 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -29,6 +29,7 @@ #include "wlan_tdls_mgmt.h" #include "wlan_tdls_cmds_process.h" #include "wlan_tdls_tgt_api.h" +#include "wlan_policy_mgr_api.h" static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj) { @@ -567,7 +568,7 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, return; if (TDLS_TEARDOWN != action_code || - tdls_soc->tdls_nss_switch_in_progress) + !tdls_soc->tdls_nss_switch_in_progress) return; if (tdls_soc->tdls_teardown_peers_cnt != 0) @@ -589,6 +590,8 @@ void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, tdls_notice("teardown done & NSS switch in progress"); tdls_soc->tdls_nss_teardown_complete = true; } + tdls_soc->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_UNKNOWN; } } @@ -2182,3 +2185,147 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req) return status; } +static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) +{ + uint8_t staidx; + struct tdls_peer *curr_peer; + struct tdls_conn_info *conn_rec; + int ret = 0; + + conn_rec = soc_obj->tdls_conn_info; + for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { + if (conn_rec[staidx].sta_id == 0) + continue; + + curr_peer = tdls_find_all_peer(soc_obj, + conn_rec[staidx].peer_mac.bytes); + if (!curr_peer) + continue; + + /* if supported only 1x1, skip it */ + if (curr_peer->spatial_streams == HW_MODE_SS_1x1) + continue; + + tdls_debug("Indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + tdls_indicate_teardown(curr_peer->vdev_priv, curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + soc_obj->tdls_teardown_peers_cnt++; + } + + if (soc_obj->tdls_teardown_peers_cnt >= 1) { + soc_obj->tdls_nss_switch_in_progress = true; + tdls_debug("TDLS peers to be torn down = %d", + soc_obj->tdls_teardown_peers_cnt); + + /* set the antenna switch transition mode */ + if (mode == HW_MODE_SS_1x1) { + soc_obj->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_2x2_to_1x1; + ret = -EAGAIN; + } else { + soc_obj->tdls_nss_transition_mode = + TDLS_NSS_TRANSITION_S_1x1_to_2x2; + ret = 0; + } + tdls_debug("TDLS teardown for antenna switch operation starts"); + } + + return ret; +} + +QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) +{ + QDF_STATUS status; + struct tdls_soc_priv_obj *soc_obj; + struct tdls_vdev_priv_obj *vdev_obj; + struct wlan_objmgr_vdev *vdev = NULL; + uint32_t vdev_nss; + int ant_switch_state = 0; + uint32_t vdev_id; + enum QDF_OPMODE opmode; + uint8_t channel; + struct tdls_osif_indication ind; + + if (!req || !req->vdev) { + tdls_err("req: %p", req); + status = QDF_STATUS_E_INVAL; + goto error; + } + + vdev = req->vdev; + status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev_obj & soc_obj"); + goto error; + } + + if (soc_obj->connected_peer_count == 0) + goto ant_sw_done; + + if (soc_obj->tdls_nss_switch_in_progress) { + if (!soc_obj->tdls_nss_teardown_complete) { + tdls_err("TDLS antenna switch is in progress"); + goto error; + } else { + goto ant_sw_done; + } + } + + vdev_id = wlan_vdev_get_id(vdev); + opmode = wlan_vdev_mlme_get_opmode(vdev); + channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); + + /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ + if (WLAN_REG_IS_24GHZ_CH(channel)) + vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_2g; + else + vdev_nss = soc_obj->tdls_configs.tdls_vdev_nss_5g; + + if (vdev_nss == HW_MODE_SS_1x1) { + tdls_debug("Supported NSS is 1x1, no need to teardown TDLS links"); + goto ant_sw_done; + } + + if (tdls_teardown_links(soc_obj, req->mode) == 0) + goto ant_sw_done; + +error: + ant_switch_state = -EAGAIN; +ant_sw_done: + if (soc_obj->tdls_event_cb) { + ind.vdev = vdev; + ind.status = ant_switch_state; + soc_obj->tdls_event_cb(soc_obj->tdls_evt_cb_data, + TDLS_EVENT_ANTENNA_SWITCH, &ind); + } + + if (soc_obj->tdls_nss_switch_in_progress && + soc_obj->tdls_nss_teardown_complete) { + soc_obj->tdls_nss_switch_in_progress = false; + soc_obj->tdls_nss_teardown_complete = false; + } + tdls_debug("tdls_nss_switch_in_progress: %d tdls_nss_teardown_complete: %d", + soc_obj->tdls_nss_switch_in_progress, + soc_obj->tdls_nss_teardown_complete); + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + return status; +} + +QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) +{ + struct tdls_antenna_switch_request *req; + + if (!msg || !msg->bodyptr) { + tdls_err("msg: 0x%pK, bodyptr: 0x%pK", msg, msg->bodyptr); + return QDF_STATUS_E_NULL_VALUE; + } + req = msg->bodyptr; + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(req); + + return QDF_STATUS_SUCCESS; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 561a40d78b..10e20cfa1b 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -249,6 +249,26 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req); */ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req); +/** + * tdls_process_antenna_switch() - handle TDLS antenna switch + * @req: TDLS antenna switch request + * + * Rely on callback to indicate the antenna switch state to caller. + * + * Return: QDF_STATUS_SUCCESS if success; other value if failed. + */ +QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req); + +/** + * tdls_antenna_switch_flush_callback() - flush TDLS antenna switch request + * @msg: scheduler message contains tdls antenna switch event + * + * This function call is invoked when scheduler thread is going down + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg); + /** * tdls_pe_del_peer() - send TDLS delete peer request to PE * @req: TDLS delete peer request diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a423dcd08a..a269a95cc6 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -292,6 +292,8 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); + case TDLS_CMD_ANTENNA_SWITCH: + tdls_process_antenna_switch(msg->bodyptr); break; case TDLS_CMD_GET_ALL_PEERS: tdls_get_all_peers_from_list(msg->bodyptr); diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index ae0a4077b2..457a3ded55 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -68,6 +68,9 @@ /** Maximum waittime for TDLS teardown links **/ #define WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS 10000 +/** Maximum waittime for TDLS antenna switch **/ +#define WAIT_TIME_FOR_TDLS_ANTENNA_SWITCH 1000 + #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 @@ -185,6 +188,7 @@ enum tdls_feature_mode { * @TDLS_CMD_TEARDOWN_LINKS: notify teardown * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list + * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -206,6 +210,7 @@ enum tdls_command_type { TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, TDLS_CMD_GET_ALL_PEERS, + TDLS_CMD_ANTENNA_SWITCH }; /** @@ -220,6 +225,7 @@ enum tdls_command_type { * @TDLS_EVENT_SETUP_REQ: setup request * @TDLS_EVENT_TEARDOWN_LINKS_DONE: teardown completion event * @TDLS_EVENT_USER_CMD: tdls user command + * @TDLS_EVENT_ANTENNA_SWITCH: antenna switch event */ enum tdls_event_type { TDLS_EVENT_VDEV_STATE_CHANGE = 0, @@ -232,6 +238,7 @@ enum tdls_event_type { TDLS_EVENT_SETUP_REQ, TDLS_EVENT_TEARDOWN_LINKS_DONE, TDLS_EVENT_USER_CMD, + TDLS_EVENT_ANTENNA_SWITCH, }; /** @@ -417,6 +424,8 @@ enum tdls_feature_bit { * @tdls_pre_off_chan_bw: tdls off channel bandwidth * @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer * @delayed_trig_framint: delayed trigger frame interval + * @tdls_vdev_nss_2g: tdls NSS setting for 2G band + * @tdls_vdev_nss_5g: tdls NSS setting for 5G band */ struct tdls_user_config { uint32_t tdls_tx_states_period; @@ -437,6 +446,8 @@ struct tdls_user_config { uint32_t tdls_pre_off_chan_bw; uint32_t tdls_peer_kickout_threshold; uint32_t delayed_trig_framint; + uint8_t tdls_vdev_nss_2g; + uint8_t tdls_vdev_nss_5g; }; /** @@ -1066,4 +1077,13 @@ struct tdls_del_all_tdls_peers { struct qdf_mac_addr bssid; }; +/** + * struct tdls_antenna_switch_request - TDLS antenna switch request + * @vdev: vdev object + * @mode: antenna mode, 1x1 or 2x2 + */ +struct tdls_antenna_switch_request { + struct wlan_objmgr_vdev *vdev; + uint32_t mode; +}; #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index f23bf52aeb..ffe3404dc6 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -212,4 +212,14 @@ void ucfg_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *mac_addr); +/** + * ucfg_tdls_antenna_switch() - tdls antenna switch + * @vdev: tdls vdev object + * @mode: antenna mode + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, + uint32_t mode); + #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 36c6318156..7ed904bd3a 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -742,3 +742,43 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, } +QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, + uint32_t mode) +{ + QDF_STATUS status; + struct tdls_antenna_switch_request *req; + struct scheduler_msg msg = {0, }; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto error; + } + + req->vdev = vdev; + req->mode = mode; + + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_antenna_switch_flush_callback; + msg.type = TDLS_CMD_ANTENNA_SWITCH; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post antenna switch msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +error: + qdf_mem_free(req); + return status; +} From c183c790f9920667e2c7c09863e7a7d48f651a54 Mon Sep 17 00:00:00 2001 From: Yun Park Date: Mon, 27 Nov 2017 10:51:53 -0800 Subject: [PATCH 34/89] qcacmn: Optimize data path logging Remove or lower log level to reduce log from data path which affects to TPUT. Change-Id: I7d4344c80cefb4a9539644ef50ff2074d80d6548 CRs-Fixed: 2143250 --- core/src/wlan_tdls_ct.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index a7636e34b5..3e9e70eb77 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -257,7 +257,6 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, uint8_t valid_mac_entries; struct tdls_conn_tracker_mac_table *mac_table; - tdls_debug("enter "); if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj)) return; @@ -296,7 +295,6 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, rx_cnt_return: qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); - tdls_debug("exit: rx pkt count %d ", mac_table[mac_cnt].rx_packet_cnt); return; } @@ -309,7 +307,6 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, uint8_t valid_mac_entries; struct tdls_conn_tracker_mac_table *mac_table; - tdls_debug("enter "); if (QDF_STATUS_SUCCESS != tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj)) return; @@ -349,7 +346,6 @@ void tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, tx_cnt_return: qdf_spin_unlock_bh(&tdls_soc_obj->tdls_ct_spinlock); - tdls_debug("exit: tx pkt count %d", mac_table[mac_cnt].tx_packet_cnt); return; } From 9b84b21a1cebc669520e4e13054cf4b87b1e5437 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 14 Dec 2017 17:02:55 -0800 Subject: [PATCH 35/89] qcacmn: Fix the TDLS command process map TDLS command processing incorrectly fall through to the wrong command, and it causes the crash in the system. Fix the mapping in TDLS process command function Change-Id: I296e10f92e283a813259e1f33143d09bcf3ab39b CRs-Fixed: 2159351 --- core/src/wlan_tdls_main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index a269a95cc6..800666feb2 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -292,6 +292,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) break; case TDLS_NOTIFY_RESET_ADAPTERS: tdls_notify_reset_adapter(msg->bodyptr); + break; case TDLS_CMD_ANTENNA_SWITCH: tdls_process_antenna_switch(msg->bodyptr); break; From 8fc14c2eca8b4aa7ac153ebfa3a245f75c4ce00c Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Wed, 29 Nov 2017 15:32:58 -0800 Subject: [PATCH 36/89] qcacmn: Correct the log level for debug messages Correct the log level for debug messages Change-Id: I847d606ea28b382c1dd449221f72822cf37f2be8 CRs-Fixed: 2160779 --- core/src/wlan_tdls_main.c | 2 +- dispatcher/src/wlan_tdls_ucfg_api.c | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 800666feb2..fc1817bcde 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -600,7 +600,7 @@ void tdls_set_ct_mode(struct wlan_objmgr_psoc *psoc) set_state: tdls_soc_obj->enable_tdls_connection_tracker = state; - tdls_notice("enable_tdls_connection_tracker %d", + tdls_debug("enable_tdls_connection_tracker %d", tdls_soc_obj->enable_tdls_connection_tracker); } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7ed904bd3a..7c5d9ad619 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -543,7 +543,7 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( mgmt_req->tdls_mgmt.len = 0; } - tdls_notice("vdev id: %d, session id : %d", mgmt_req->vdev_id, + tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id, mgmt_req->session_id); msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; @@ -589,14 +589,14 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) tdls_err("vdev is NULL "); return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TEARDOWN_LINKS; status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return status; } @@ -628,7 +628,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( notify_info->vdev, notify_info); return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) @@ -645,7 +645,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.type = TDLS_NOTIFY_STA_CONNECTION; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } @@ -661,7 +661,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) @@ -679,7 +679,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.type = TDLS_NOTIFY_STA_DISCONNECTION; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } @@ -696,7 +696,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( return QDF_STATUS_E_NULL_VALUE; } - tdls_notice("Enter "); + tdls_debug("Enter "); set_mode = qdf_mem_malloc(sizeof(*set_mode)); if (!set_mode) @@ -712,7 +712,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( msg.type = TDLS_CMD_SET_TDLS_MODE; scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); - tdls_notice("Exit "); + tdls_debug("Exit "); return QDF_STATUS_SUCCESS; } From 90b989b050db6c079652ae238d1189442b884063 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 10 Jan 2018 13:46:50 +0800 Subject: [PATCH 37/89] qcacmn: Fix tdls KW issues Fix static code analysis issues in tdls component: NULL pointer dereference - tdls_process_antenna_switch - tdls_antenna_switch_flush_callback - tdls_indicate_teardown - ucfg_tdls_notify_sta_connect - ucfg_tdls_notify_sta_disconnect - ucfg_tdls_set_operating_mode Change-Id: I3bb72658dcd3116f6f64da15a7039f49157a0f3f CRs-Fixed: 2169736 --- core/src/wlan_tdls_cmds_process.c | 20 ++++++++++++-------- core/src/wlan_tdls_ct.c | 13 +++++++++---- dispatcher/src/wlan_tdls_ucfg_api.c | 11 ++++------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index e934f4f49a..9619533537 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -2249,16 +2249,18 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) struct tdls_osif_indication ind; if (!req || !req->vdev) { - tdls_err("req: %p", req); - status = QDF_STATUS_E_INVAL; - goto error; + tdls_err("Invalid input params req: %p", req); + if (req) + qdf_mem_free(req); + + return QDF_STATUS_E_INVAL; } vdev = req->vdev; status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get vdev_obj & soc_obj"); - goto error; + goto get_obj_err; } if (soc_obj->connected_peer_count == 0) @@ -2267,7 +2269,7 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) if (soc_obj->tdls_nss_switch_in_progress) { if (!soc_obj->tdls_nss_teardown_complete) { tdls_err("TDLS antenna switch is in progress"); - goto error; + goto ant_sw_in_progress; } else { goto ant_sw_done; } @@ -2291,7 +2293,7 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) if (tdls_teardown_links(soc_obj, req->mode) == 0) goto ant_sw_done; -error: +ant_sw_in_progress: ant_switch_state = -EAGAIN; ant_sw_done: if (soc_obj->tdls_event_cb) { @@ -2310,8 +2312,10 @@ ant_sw_done: soc_obj->tdls_nss_switch_in_progress, soc_obj->tdls_nss_teardown_complete); +get_obj_err: wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); + return status; } @@ -2320,7 +2324,7 @@ QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) struct tdls_antenna_switch_request *req; if (!msg || !msg->bodyptr) { - tdls_err("msg: 0x%pK, bodyptr: 0x%pK", msg, msg->bodyptr); + tdls_err("msg: 0x%pK", msg); return QDF_STATUS_E_NULL_VALUE; } req = msg->bodyptr; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 3e9e70eb77..e55bea3727 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -509,10 +509,15 @@ void tdls_indicate_teardown(struct tdls_vdev_priv_obj *tdls_vdev, struct tdls_soc_priv_obj *tdls_soc; struct tdls_osif_indication indication; + if (!tdls_vdev || !curr_peer) { + tdls_err("tdls_vdev: %pK, curr_peer: %pK", + tdls_vdev, curr_peer); + return; + } + tdls_soc = wlan_vdev_get_tdls_soc_obj(tdls_vdev->vdev); - if (!tdls_soc || !tdls_vdev || !curr_peer) { - tdls_err("tdls_soc: %pK, tdls_vdev: %pK, curr_peer: %pK", - tdls_soc, tdls_vdev, curr_peer); + if (!tdls_soc) { + tdls_err("tdls_soc: %pK", tdls_soc); return; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 7c5d9ad619..583b8c53ee 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -624,8 +624,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %pK, notify_info %pK", - notify_info->vdev, notify_info); + tdls_err("notify_info %pK", notify_info); return QDF_STATUS_E_NULL_VALUE; } tdls_debug("Enter "); @@ -656,8 +655,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( struct tdls_sta_notify_params *notify; if (!notify_info || !notify_info->vdev) { - tdls_err("notify_info->vdev: %pK, notify_info %pK", - notify_info->vdev, notify_info); + tdls_err("notify_info %pK", notify_info); return QDF_STATUS_E_NULL_VALUE; } @@ -691,8 +689,7 @@ QDF_STATUS ucfg_tdls_set_operating_mode( struct tdls_set_mode_params *set_mode; if (!set_mode_params || !set_mode_params->vdev) { - tdls_err("vdev: %pK, set_mode_params %pK", - set_mode_params->vdev, set_mode_params); + tdls_err("set_mode_params %pK", set_mode_params); return QDF_STATUS_E_NULL_VALUE; } From 93667779c82255469d932e01b0681c3a1cc36b95 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 16 Jan 2018 01:52:25 -0800 Subject: [PATCH 38/89] qcacmn: Fix TDLS wpa2 teardown failures TDLS teardown request from the DUT is dropped in the peer, due to invalid MIC in the teardown frame. TDLS responder value is not set correctly in TDLS teardown frame, and it causes MIC failures in the peer device. Set the correct responder value in TDLS teardown frame. Change-Id: Ibe056c89f644c094a10f7a5eb51b6d90a13a4a01 CRs-Fixed: 2155555 --- core/src/wlan_tdls_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index c7582196e8..8dfae9f15f 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -386,7 +386,7 @@ QDF_STATUS tdls_process_mgmt_req( * after the cmd validation */ tdls_mgmt_req->tdls_mgmt.responder = - tdls_mgmt_req->chk_frame->responder; + !tdls_mgmt_req->chk_frame->responder; tdls_mgmt_req->tdls_mgmt.status_code = tdls_mgmt_req->chk_frame->status_code; From ab13769063f8998102b7bdefa741a4723b413fb6 Mon Sep 17 00:00:00 2001 From: Zhu Jianmin Date: Tue, 9 Jan 2018 12:49:35 +0800 Subject: [PATCH 39/89] qcacmn: Avoid using tdls_soc_obj after it has been freed Object tdls_soc_obj is being used ever after it has been freed which creates stability issue. Fix it by returning up on releasing the memory. Change-Id: I0b3faf2435396f2e3cd92bc18afc263f3280eae3 CRs-Fixed: 2164332 --- core/src/wlan_tdls_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index fc1817bcde..7e447d3eba 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -61,6 +61,7 @@ QDF_STATUS tdls_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach psoc tdls component"); qdf_mem_free(tdls_soc_obj); + return status; } tdls_soc_global = tdls_soc_obj; @@ -88,7 +89,6 @@ QDF_STATUS tdls_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, if (QDF_IS_STATUS_ERROR(status)) tdls_err("Failed to detach psoc tdls component"); - qdf_mem_free(tdls_soc_obj); return status; From 67427ce6e57ae905fcc30807f226f9a4d4381b21 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Sun, 14 Jan 2018 22:13:16 -0800 Subject: [PATCH 40/89] qcacmn: tdls: Fix instances of unadorned %p Fix instances of unadorned %p in tdls. Change-Id: I5faad47ad7bdcc6f079466c277a88b5a21719e2c CRs-Fixed: 2170907 --- core/src/wlan_tdls_cmds_process.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 9619533537..ecae73b711 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -2248,15 +2248,18 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) uint8_t channel; struct tdls_osif_indication ind; - if (!req || !req->vdev) { - tdls_err("Invalid input params req: %p", req); - if (req) - qdf_mem_free(req); - + if (!req) { + tdls_err("null req"); return QDF_STATUS_E_INVAL; } vdev = req->vdev; + if (!vdev) { + tdls_err("null vdev"); + qdf_mem_free(req); + return QDF_STATUS_E_INVAL; + } + status = tdls_get_vdev_objects(vdev, &vdev_obj, &soc_obj); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't get vdev_obj & soc_obj"); From 759661d38d32758c622a6beec23f00e461d355e4 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Thu, 25 Jan 2018 11:46:31 -0800 Subject: [PATCH 41/89] qcacmn: Replace QDF_MAC_ADDRESS_STR QDF_MAC_ADDRESS_STR has been depreciated in favor of QDF_MAC_ADDR_STR. Replace all usages with the new macro. Change-Id: I534923783a32288f7861caf9ae52ca3aac965809 CRs-Fixed: 2179126 --- core/src/wlan_tdls_cmds_process.c | 70 ++++++++++++++--------------- core/src/wlan_tdls_ct.c | 31 +++++++------ core/src/wlan_tdls_main.c | 4 +- core/src/wlan_tdls_mgmt.c | 2 +- core/src/wlan_tdls_peer.c | 12 ++--- dispatcher/src/wlan_tdls_tgt_api.c | 4 +- dispatcher/src/wlan_tdls_ucfg_api.c | 2 +- 7 files changed, 62 insertions(+), 63 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ecae73b711..f8622a82cf 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -163,7 +163,7 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) qdf_mem_copy(addstareq->peermac.bytes, req->add_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; @@ -228,7 +228,7 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) qdf_mem_copy(delstareq->peermac.bytes, req->del_peer_req.peer_addr, QDF_MAC_ADDR_SIZE); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); msg.type = soc_obj->tdls_del_sta_req; msg.bodyptr = delstareq; @@ -313,7 +313,7 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) qdf_mem_copy(&addstareq->supported_rates, update_peer->supported_rates, update_peer->supported_rates_len); - tdls_debug("for " QDF_MAC_ADDRESS_STR, + tdls_debug("for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; @@ -452,7 +452,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) peer = tdls_get_peer(vdev_obj, mac); if (!peer) { - tdls_err("peer: " QDF_MAC_ADDRESS_STR " not exist. invalid", + tdls_err("peer: " QDF_MAC_ADDR_STR " not exist. invalid", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto addrsp; @@ -469,7 +469,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_PERM; goto setlink; @@ -478,7 +478,7 @@ static QDF_STATUS tdls_activate_add_peer(struct tdls_add_peer_request *req) /* first to check if we reached to maximum supported TDLS peer. */ curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " Request declined. Current %d, Max allowed %d.", QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); @@ -629,7 +629,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * there is no harm to double-check. */ if (TDLS_SETUP_REQUEST == tdls_validate->action_code) { - tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", + tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, @@ -641,7 +641,7 @@ static int tdls_validate_setup_frames(struct tdls_soc_priv_obj *tdls_soc, * code to supplicant */ tdls_validate->status_code = QDF_STATUS_E_RESOURCES; - tdls_err(QDF_MAC_ADDRESS_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", + tdls_err(QDF_MAC_ADDR_STR " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_soc->connected_peer_count, @@ -690,7 +690,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) /* if tdls_mode is disabled, then decline the peer's request */ if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode || TDLS_SUPPORT_SUSPENDED == tdls_soc->tdls_current_mode) { - tdls_notice(QDF_MAC_ADDRESS_STR + tdls_notice(QDF_MAC_ADDR_STR " TDLS mode is disabled. action %d declined.", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code); @@ -698,7 +698,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } if (tdls_soc->tdls_nss_switch_in_progress) { tdls_err("nss switch in progress, action %d declined " - QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_STR, tdls_validate->action_code, QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); return -EAGAIN; @@ -709,7 +709,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (NULL != tdls_is_progress(tdls_vdev, tdls_validate->peer_mac, true)) { tdls_err("setup is ongoing. action %d declined for " - QDF_MAC_ADDRESS_STR, + QDF_MAC_ADDR_STR, tdls_validate->action_code, QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac)); return -EPERM; @@ -742,7 +742,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) tdls_validate->peer_mac); if (curr_peer) { if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - tdls_err(QDF_MAC_ADDRESS_STR " already connected action %d declined.", + tdls_err(QDF_MAC_ADDR_STR " already connected action %d declined.", QDF_MAC_ADDR_ARRAY( tdls_validate->peer_mac), tdls_validate->action_code); @@ -753,7 +753,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } } - tdls_notice("tdls_mgmt" QDF_MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu", + tdls_notice("tdls_mgmt" QDF_MAC_ADDR_STR " action %d, dialog_token %d status %d, len = %zu", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), tdls_validate->action_code, tdls_validate->dialog_token, tdls_validate->status_code, tdls_validate->len); @@ -763,7 +763,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_TEARDOWN == tdls_validate->action_code) { temp_peer = tdls_find_peer(tdls_vdev, tdls_validate->peer_mac); if (!temp_peer) { - tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist", + tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist", QDF_MAC_ADDR_ARRAY( tdls_validate->peer_mac)); return -EPERM; @@ -772,7 +772,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) if (TDLS_IS_LINK_CONNECTED(temp_peer)) tdls_validate->responder = temp_peer->is_responder; else { - tdls_err(QDF_MAC_ADDRESS_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", + tdls_err(QDF_MAC_ADDR_STR " peer doesn't exist or not connected %d dialog_token %d status %d, tdls_validate->len = %zu", QDF_MAC_ADDR_ARRAY(tdls_validate->peer_mac), temp_peer->link_status, tdls_validate->dialog_token, @@ -889,7 +889,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) curr_peer = tdls_get_peer(vdev_obj, mac); if (!curr_peer) { - tdls_err(QDF_MAC_ADDRESS_STR " not exist. return invalid", + tdls_err(QDF_MAC_ADDR_STR " not exist. return invalid", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto updatersp; @@ -898,7 +898,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) /* in change station, we accept only when sta_id is valid */ if (curr_peer->link_status > TDLS_LINK_CONNECTING || !(TDLS_STA_INDEX_CHECK(curr_peer->sta_id))) { - tdls_err(QDF_MAC_ADDRESS_STR " link %d. sta %d. update peer %s", + tdls_err(QDF_MAC_ADDR_STR " link %d. sta %d. update peer %s", QDF_MAC_ADDR_ARRAY(mac), curr_peer->link_status, curr_peer->sta_id, (TDLS_STA_INDEX_CHECK(curr_peer->sta_id)) ? "ignored" @@ -910,7 +910,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) /* when others are on-going, we want to change link_status to idle */ if (tdls_is_progress(vdev_obj, mac, true)) { - tdls_notice(QDF_MAC_ADDRESS_STR " TDLS setuping. Req declined.", + tdls_notice(QDF_MAC_ADDR_STR " TDLS setuping. Req declined.", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_PERM; goto setlink; @@ -918,7 +918,7 @@ tdls_activate_update_peer(struct tdls_update_peer_request *req) curr_tdls_peers = tdls_get_connected_peer(soc_obj); if (soc_obj->max_num_tdls_sta <= curr_tdls_peers) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " Request declined. Current: %d, Max allowed: %d.", QDF_MAC_ADDR_ARRAY(mac), curr_tdls_peers, soc_obj->max_num_tdls_sta); @@ -1159,7 +1159,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " not found, ignore NL80211_TDLS_ENABLE_LINK", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; @@ -1404,7 +1404,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, &rsp->peermac); tdls_warn("TDLS: STA IDX at %d is %d of mac " - QDF_MAC_ADDRESS_STR, sta_idx, + QDF_MAC_ADDR_STR, sta_idx, rsp->sta_id, QDF_MAC_ADDR_ARRAY (rsp->peermac.bytes)); break; @@ -1467,7 +1467,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) const uint8_t *macaddr; struct tdls_osif_indication ind; - tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDRESS_STR, + tdls_debug("del peer rsp: vdev %d peer " QDF_MAC_ADDR_STR, rsp->session_id, QDF_MAC_ADDR_ARRAY(rsp->peermac.bytes)); psoc = rsp->psoc; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, rsp->session_id, @@ -1495,7 +1495,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) tdls_warn("TDLS: del STA IDX = %x", rsp->sta_id); curr_peer = tdls_find_peer(vdev_obj, macaddr); if (curr_peer) { - tdls_debug(QDF_MAC_ADDRESS_STR " status is %d", + tdls_debug(QDF_MAC_ADDR_STR " status is %d", QDF_MAC_ADDR_ARRAY(macaddr), curr_peer->link_status); @@ -1556,7 +1556,7 @@ tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, struct scheduler_msg msg = {0,}; QDF_STATUS status; - tdls_debug("update TDLS peer " QDF_MAC_ADDRESS_STR " vdev %d, state %d", + tdls_debug("update TDLS peer " QDF_MAC_ADDR_STR " vdev %d, state %d", QDF_MAC_ADDR_ARRAY(peer_state->peer_macaddr), peer_state->vdev_id, peer_state->peer_state); msg.type = soc_obj->tdls_update_peer_state; @@ -1661,17 +1661,17 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) mac = req->peer_addr; peer = tdls_find_peer(vdev_obj, mac); if (!peer) { - tdls_err(QDF_MAC_ADDRESS_STR + tdls_err(QDF_MAC_ADDR_STR " not found, ignore NL80211_TDLS_ENABLE_LINK", QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto error; } - tdls_debug("enable link for peer " QDF_MAC_ADDRESS_STR " link state %d", + tdls_debug("enable link for peer " QDF_MAC_ADDR_STR " link state %d", QDF_MAC_ADDR_ARRAY(mac), peer->link_status); if (!TDLS_STA_INDEX_CHECK(peer->sta_id)) { - tdls_err("invalid sta idx %u for " QDF_MAC_ADDRESS_STR, + tdls_err("invalid sta idx %u for " QDF_MAC_ADDR_STR, peer->sta_id, QDF_MAC_ADDR_ARRAY(mac)); status = QDF_STATUS_E_INVAL; goto error; @@ -1757,7 +1757,7 @@ static QDF_STATUS tdls_config_force_peer( struct tdls_peer_update_state *peer_update_param; macaddr = req->peer_addr; - tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDRESS_STR, + tdls_debug("NL80211_TDLS_SETUP for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; @@ -1785,7 +1785,7 @@ static QDF_STATUS tdls_config_force_peer( peer = tdls_get_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer " QDF_MAC_ADDRESS_STR " does not exist", + tdls_err("peer " QDF_MAC_ADDR_STR " does not exist", QDF_MAC_ADDR_ARRAY(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; @@ -1847,7 +1847,7 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req) struct wlan_objmgr_vdev *vdev; QDF_STATUS status; - tdls_debug("Configure external TDLS peer " QDF_MAC_ADDRESS_STR, + tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(req->peer_addr)); /* reference cnt is acquired in ucfg_tdls_oper */ @@ -1893,7 +1893,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) struct tdls_osif_indication ind; macaddr = req->peer_addr; - tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDRESS_STR, + tdls_debug("NL80211_TDLS_TEARDOWN for " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); vdev = req->vdev; @@ -1922,7 +1922,7 @@ QDF_STATUS tdls_process_remove_force_peer(struct tdls_oper_request *req) peer = tdls_find_peer(vdev_obj, macaddr); if (!peer) { - tdls_err("peer matching " QDF_MAC_ADDRESS_STR " not found", + tdls_err("peer matching " QDF_MAC_ADDR_STR " not found", QDF_MAC_ADDR_ARRAY(macaddr)); status = QDF_STATUS_E_NULL_VALUE; goto error; @@ -2013,7 +2013,7 @@ QDF_STATUS tdls_process_should_discover(struct wlan_objmgr_vdev *vdev, vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); type = evt->message_type; - tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", tdls_evt_to_str(type), QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); @@ -2070,7 +2070,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); vdev_obj = wlan_vdev_get_tdls_vdev_obj(vdev); - tdls_debug("TDLS %s: " QDF_MAC_ADDRESS_STR "reason %d", + tdls_debug("TDLS %s: " QDF_MAC_ADDR_STR "reason %d", tdls_evt_to_str(type), QDF_MAC_ADDR_ARRAY(evt->peermac.bytes), evt->peer_reason); @@ -2088,7 +2088,7 @@ QDF_STATUS tdls_process_should_teardown(struct wlan_objmgr_vdev *vdev, reason = evt->peer_reason; if (TDLS_LINK_CONNECTED == curr_peer->link_status) { - tdls_err("%s reason: %d for" QDF_MAC_ADDRESS_STR, + tdls_err("%s reason: %d for" QDF_MAC_ADDR_STR, tdls_evt_to_str(type), evt->peer_reason, QDF_MAC_ADDR_ARRAY(evt->peermac.bytes)); if (reason == TDLS_TEARDOWN_RSSI || diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e55bea3727..2327fc4744 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -127,8 +127,8 @@ void tdls_discovery_timeout_peer_cb(void *user_data) &p_node); continue; } - tdls_debug(QDF_MAC_ADDRESS_STR " to idle state", - QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); + tdls_debug(QDF_MAC_ADDR_STR " to idle state", + QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); tdls_set_peer_link_status(peer, TDLS_LINK_IDLE, TDLS_LINK_NOT_SUPPORTED); @@ -379,8 +379,8 @@ void tdls_implicit_send_discovery_request( /* This function is called in mutex_lock */ temp_peer = tdls_is_progress(tdls_vdev_obj, NULL, 0); if (NULL != temp_peer) { - tdls_notice(QDF_MAC_ADDRESS_STR " ongoing. pre_setup ignored", - QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); + tdls_notice(QDF_MAC_ADDR_STR " ongoing. pre_setup ignored", + QDF_MAC_ADDR_ARRAY(temp_peer->peer_mac.bytes)); goto done; } @@ -446,7 +446,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, if (0 == tdls_vdev->discovery_sent_cnt) qdf_mc_timer_stop(&tdls_vdev->peer_discovery_timer); - tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDRESS_STR + tdls_debug("Discovery(%u) Response from " QDF_MAC_ADDR_STR " link_status %d", tdls_vdev->discovery_sent_cnt, QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->link_status); @@ -462,7 +462,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, tdls_set_peer_link_status(curr_peer, TDLS_LINK_DISCOVERED, TDLS_LINK_SUCCESS); - tdls_debug("Rssi Threshold met: " QDF_MAC_ADDRESS_STR + tdls_debug("Rssi Threshold met: " QDF_MAC_ADDR_STR " rssi = %d threshold= %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->rssi, @@ -477,8 +477,7 @@ int tdls_recv_discovery_resp(struct tdls_vdev_priv_obj *tdls_vdev, TDLS_EVENT_SETUP_REQ, &indication); } else { - tdls_debug("Rssi Threshold not met: " - QDF_MAC_ADDRESS_STR + tdls_debug("Rssi Threshold not met: " QDF_MAC_ADDR_STR " rssi = %d threshold = %d ", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->rssi, @@ -601,7 +600,7 @@ tdls_ct_process_idle_handler( return; } - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->tx_pkt, @@ -616,12 +615,12 @@ tdls_ct_process_idle_handler( (curr_peer->rx_pkt >= tdls_vdev_obj->threshold_config.idle_packet_n)) { /* this tdls link got back to normal, so keep it */ - tdls_debug("tdls link to " QDF_MAC_ADDRESS_STR + tdls_debug("tdls link to " QDF_MAC_ADDR_STR " back to normal, will stay", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); } else { /* this tdls link needs to get torn down */ - tdls_notice("trigger tdls link to "QDF_MAC_ADDRESS_STR" down", + tdls_notice("trigger tdls link to "QDF_MAC_ADDR_STR" down", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_indicate_teardown(tdls_vdev_obj, curr_peer, @@ -705,7 +704,7 @@ static void tdls_ct_process_connected_link( if ((int32_t)curr_peer->rssi < (int32_t)tdls_vdev->threshold_config.rssi_teardown_threshold) { - tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDRESS_STR "!", + tdls_warn("Tear down - low RSSI: " QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_indicate_teardown(tdls_vdev, curr_peer, @@ -736,7 +735,7 @@ static void tdls_ct_process_connected_link( if (QDF_TIMER_STATE_RUNNING != curr_peer->peer_idle_timer.state) { tdls_warn("Tx/Rx Idle timer start: " - QDF_MAC_ADDRESS_STR "!", + QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); tdls_timer_restart(tdls_vdev->vdev, &curr_peer->peer_idle_timer, @@ -744,7 +743,7 @@ static void tdls_ct_process_connected_link( } } else if (QDF_TIMER_STATE_RUNNING == curr_peer->peer_idle_timer.state) { - tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDRESS_STR "!", + tdls_warn("Tx/Rx Idle timer stop: " QDF_MAC_ADDR_STR "!", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes)); qdf_mc_timer_stop(&curr_peer->peer_idle_timer); } @@ -853,7 +852,7 @@ static void tdls_ct_process_peers(struct tdls_peer *curr_peer, struct tdls_vdev_priv_obj *tdls_vdev_obj, struct tdls_soc_priv_obj *tdls_soc_obj) { - tdls_debug(QDF_MAC_ADDRESS_STR " link_status %d tdls_support %d", + tdls_debug(QDF_MAC_ADDR_STR " link_status %d tdls_support %d", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->link_status, curr_peer->tdls_support); @@ -1116,7 +1115,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, qdf_mem_copy(&chan_switch_params.peer_mac_addr, &conn_peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE); - tdls_notice("Peer " QDF_MAC_ADDRESS_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", + tdls_notice("Peer " QDF_MAC_ADDR_STR " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d", QDF_MAC_ADDR_ARRAY(chan_switch_params.peer_mac_addr), chan_switch_params.vdev_id, chan_switch_params.tdls_off_ch, diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 7e447d3eba..bfe79473ef 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1058,7 +1058,7 @@ static int __tdls_get_all_peers_from_list( if (buf_len < 32 + 1) break; len = qdf_scnprintf(buf, buf_len, - QDF_MAC_ADDRESS_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), curr_peer->sta_id, (curr_peer->tdls_support == @@ -1413,7 +1413,7 @@ QDF_STATUS tdls_scan_callback(struct tdls_soc_priv_obj *tdls_soc) curr_peer = tdls_is_progress(tdls_vdev, NULL, 0); if (NULL != curr_peer) { if (tdls_soc->scan_reject_count++ >= TDLS_SCAN_REJECT_MAX) { - tdls_notice(QDF_MAC_ADDRESS_STR + tdls_notice(QDF_MAC_ADDR_STR ". scan rejected %d. force it to idle", QDF_MAC_ADDR_ARRAY( curr_peer->peer_mac.bytes), diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 8dfae9f15f..b271b3209a 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -107,7 +107,7 @@ static QDF_STATUS tdls_process_rx_mgmt( TDLS_PUBLIC_ACTION_DISC_RESP) { mac = &rx_mgmt->buf[TDLS_80211_PEER_ADDR_OFFSET]; tdls_notice("[TDLS] TDLS Discovery Response," - QDF_MAC_ADDRESS_STR " RSSI[%d] <--- OTA", + QDF_MAC_ADDR_STR " RSSI[%d] <--- OTA", QDF_MAC_ADDR_ARRAY(mac), rx_mgmt->rx_rssi); tdls_recv_discovery_resp(tdls_vdev, mac); tdls_set_rssi(tdls_vdev, mac, rx_mgmt->rx_rssi); diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 769ba53342..a254ff5fd3 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -59,7 +59,7 @@ struct tdls_peer *tdls_find_peer(struct tdls_vdev_priv_obj *vdev_obj, status = qdf_list_peek_next(head, p_node, &p_node); } - tdls_debug("no tdls peer " QDF_MAC_ADDRESS_STR, + tdls_debug("no tdls peer " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); return NULL; } @@ -188,7 +188,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, qdf_list_insert_back(head, &peer->node); - tdls_debug("add tdls peer: " QDF_MAC_ADDRESS_STR, + tdls_debug("add tdls peer: " QDF_MAC_ADDR_STR, QDF_MAC_ADDR_ARRAY(macaddr)); return peer; } @@ -222,7 +222,7 @@ tdls_find_progress_peer_in_list(qdf_list_t *head, status = qdf_list_peek_next(head, p_node, &p_node); continue; } else if (TDLS_LINK_CONNECTING == peer->link_status) { - tdls_debug(QDF_MAC_ADDRESS_STR " TDLS_LINK_CONNECTING", + tdls_debug(QDF_MAC_ADDR_STR " TDLS_LINK_CONNECTING", QDF_MAC_ADDR_ARRAY(peer->peer_mac.bytes)); return peer; } @@ -353,7 +353,7 @@ tdls_find_first_connected_peer(struct tdls_vdev_priv_obj *vdev_obj) peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && TDLS_LINK_CONNECTED == peer->link_status) { - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR " TDLS_LINK_CONNECTED", QDF_MAC_ADDR_ARRAY( peer->peer_mac.bytes)); @@ -795,7 +795,7 @@ void tdls_peer_idle_timers_destroy(struct tdls_vdev_priv_obj *vdev_obj) while (QDF_IS_STATUS_SUCCESS(status)) { peer = qdf_container_of(p_node, struct tdls_peer, node); if (peer && peer->is_peer_idle_timer_initialised) { - tdls_debug(QDF_MAC_ADDRESS_STR + tdls_debug(QDF_MAC_ADDR_STR ": destroy idle timer ", QDF_MAC_ADDR_ARRAY( peer->peer_mac.bytes)); diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 8b35247d8b..c89e202e20 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -183,7 +183,7 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, tdls_err("psoc: 0x%pK, info: 0x%pK", psoc, info); return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDRESS_STR, + tdls_debug("vdev: %d, type: %d, reason: %d" QDF_MAC_ADDR_STR, info->vdev_id, info->message_type, info->peer_reason, QDF_MAC_ADDR_ARRAY(info->peermac.bytes)); notify = qdf_mem_malloc(sizeof(*notify)); diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 583b8c53ee..1bae8eb0a6 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -449,7 +449,7 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_NULL_VALUE; } - tdls_debug("%s for peer " QDF_MAC_ADDRESS_STR, + tdls_debug("%s for peer " QDF_MAC_ADDR_STR, tdls_get_oper_str(cmd), QDF_MAC_ADDR_ARRAY(macaddr)); From 97e0192b6581bd03b8459b0fd09aeb5b66dfc9c4 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 8 Feb 2018 21:20:38 -0800 Subject: [PATCH 42/89] qcacmn: Fix memory leak in TDLS rx mgmt callback TDLS RX management callback needs to be registered only during driver load time. Remove the redundant callback registration. Change-Id: Iee0e781ade2a4dafaaf372e8a9078347493418df CRs-Fixed: 2185908 --- core/src/wlan_tdls_main.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index bfe79473ef..782408f6d0 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -833,14 +833,6 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_debug("TDLS Set state cnt %d", tdls_soc_obj->set_state_info.set_state_cnt); - - if (tdls_soc_obj->set_state_info.set_state_cnt == 1) - /* register callbacks with tx/rx mgmt */ - tdls_mgmt_rx_ops(tdls_soc_obj->soc, true); - else - /* deregister callbacks with tx/rx mgmt */ - tdls_mgmt_rx_ops(tdls_soc_obj->soc, false); - done: qdf_mem_free(tdls_info_to_fw); return; From 31dade3142955b1e63a274215205cb5ad4a41b51 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Thu, 1 Mar 2018 15:31:35 -0800 Subject: [PATCH 43/89] qcacmn: Introduce new versions of TDLS peer callbacks The parameters to function typedef tdls_register_tl_peer_callback() currently includes ucastsig. This "unicast signature" parameter dates back to a previous version of the driver that used signatures to synchronize the data plane with the control plane. However the current version of the driver does not use this mechanism, so there is a desire to remove this parameter from the callback. In addition both typedef tdls_register_tl_peer_callback() and typedef tdls_deregister_tl_peer_callback() suffer from poor naming since the "_tl_" in the names refers to a datapath component that was present in an older version of the driver but which is no longer present. Therefore introduce a new version of these typedefs with better naming and which removes the ucastsig parameter. Use temporary conditional compilation to allow support for both the old and new interfaces until such time as all registrants have converted to the new interfaces. This is part of the plan to completely remove the obsolete unicast and broadcast signatures from throughout the driver. Change-Id: Id4ea23266b0f3e1480b645c5afce6c17585ccb46 CRs-Fixed: 2200931 --- core/src/wlan_tdls_cmds_process.c | 22 +++++++++++++- core/src/wlan_tdls_ct.c | 9 +++++- core/src/wlan_tdls_main.h | 18 ++++++++++-- dispatcher/inc/wlan_tdls_public_structs.h | 36 +++++++++++++++++++++-- dispatcher/src/wlan_tdls_ucfg_api.c | 7 +++++ 5 files changed, 84 insertions(+), 8 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index f8622a82cf..06f6813a6c 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1501,6 +1501,19 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) id = wlan_vdev_get_id(vdev); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + if (TDLS_IS_LINK_CONNECTED(curr_peer)) { + soc_obj->tdls_dereg_peer( + soc_obj->tdls_peer_context, + id, curr_peer->sta_id); + tdls_decrement_peer_count(soc_obj); + } else if (TDLS_LINK_CONNECTING == + curr_peer->link_status) { + soc_obj->tdls_dereg_peer( + soc_obj->tdls_peer_context, + id, curr_peer->sta_id); + } +#else if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_tl_peer( soc_obj->tdls_tl_peer_data, @@ -1512,6 +1525,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj->tdls_tl_peer_data, id, curr_peer->sta_id); } +#endif } tdls_reset_peer(vdev_obj, macaddr); conn_rec[sta_idx].sta_id = 0; @@ -1683,11 +1697,17 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) TDLS_LINK_SUCCESS); id = wlan_vdev_get_id(vdev); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, + id, mac, peer->sta_id, + peer->qos); +#else status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, id, mac, peer->sta_id, peer->signature, peer->qos); +#endif if (QDF_IS_STATUS_ERROR(status)) { - tdls_err("TDLS register with TL fail, status %d", status); + tdls_err("TDLS register peer fail, status %d", status); goto error; } diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 2327fc4744..d6839a3e27 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1274,12 +1274,19 @@ void tdls_disable_offchan_and_teardown_links( */ tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + if (tdls_soc->tdls_dereg_peer) + tdls_soc->tdls_dereg_peer( + tdls_soc->tdls_peer_context, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); +#else if (tdls_soc->tdls_dereg_tl_peer) tdls_soc->tdls_dereg_tl_peer( tdls_soc->tdls_tl_peer_data, wlan_vdev_get_id(vdev), curr_peer->sta_id); - +#endif tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = 0; tdls_soc->tdls_conn_info[staidx].session_id = 255; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 0dee99c63f..14b2b65ca1 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -170,9 +170,15 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + * @tdls_peer_context: userdata for register/deregister TDLS peer + * @tdls_reg_peer: register tdls peer with datapath + * @tdls_dereg_peer: deregister tdls peer from datapath +#else + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tdls_reg_tl_peer: callback to register the TDLS peer with TL * @tdls_dereg_tl_peer: callback to unregister the TDLS peer - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer +#endif * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value @@ -213,10 +219,16 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + void *tdls_peer_context; + tdls_register_peer_callback tdls_reg_peer; + tdls_deregister_peer_callback tdls_dereg_peer; +#else + void *tdls_tl_peer_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; +#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; - void *tdls_tl_peer_data; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; uint16_t tdls_send_mgmt_req; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 457a3ded55..0ada980ae6 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -547,6 +547,22 @@ typedef void (*tdls_evt_callback) (void *data, typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, struct tdls_tx_cnf *tx_ack_cnf_cb_data); +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + +/* This callback is used to register TDLS peer with the datapath */ +typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, + uint32_t vdev_id, + const uint8_t *mac, + uint16_t stat_id, + uint8_t qos); + +/* This callback is used to deregister TDLS peer from the datapath */ +typedef QDF_STATUS (*tdls_deregister_peer_callback)(void *userdata, + uint32_t vdev_id, + uint8_t sta_id); + +#else + /* This callback is used to register TDLS peer with TL */ typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, uint32_t vdev_id, @@ -560,6 +576,8 @@ typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); +#endif + /* This callback is used to update datapath vdev flags */ typedef QDF_STATUS (*tdls_dp_vdev_update_flags_callback)(void *cbk_data, @@ -580,10 +598,16 @@ typedef QDF_STATUS * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + * @tdls_peer_context: userdata for register/deregister TDLS peer + * @tdls_reg_peer: register tdls peer with datapath + * @tdls_dereg_peer: deregister tdls peer from datapath +#else + * @tdls_tl_peer_data: userdata for register/deregister TDLS peer * @tdls_reg_tl_peer: tdls register tdls peer * @tdls_dereg_tl_peer: tdls deregister tdls peer +#endif * @tdls_dp_vdev_update: update vdev flags in datapath - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer */ struct tdls_start_params { struct tdls_user_config config; @@ -601,10 +625,16 @@ struct tdls_start_params { void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + void *tdls_peer_context; + tdls_register_peer_callback tdls_reg_peer; + tdls_deregister_peer_callback tdls_dereg_peer; +#else + void *tdls_tl_peer_data; tdls_register_tl_peer_callback tdls_reg_tl_peer; tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; +#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; - void *tdls_tl_peer_data; }; /** diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 1bae8eb0a6..f4aecc1502 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -207,10 +207,17 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; +#ifdef USE_NEW_TDLS_PEER_CALLBACKS + /* Save callbacks to register/deregister TDLS sta with TL */ + soc_obj->tdls_reg_peer = req->tdls_reg_peer; + soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; + soc_obj->tdls_peer_context = req->tdls_peer_context; +#else /* Save callbacks to register/deregister TDLS sta with TL */ soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; +#endif /* Save legacy PE/WMA commands in TDLS soc object */ soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; From 1f5b24e8b550bfec84a892bd8bb93fd7b92066a9 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 2 Mar 2018 08:48:24 -0800 Subject: [PATCH 44/89] qcacmn: Remove obsolete TDLS peer callback interface Change "qcacmn: Introduce new versions of TDLS peer callbacks" (Change-Id Id4ea23266b0f3e1480b645c5afce6c17585ccb46) introduced a new interface which removed an unused parameter and changed obsolete naming. Subsequently change "qcacld-3.0: Use new TDLS peer callback interface" (Change-Id: I5c4684ac0a62f314da26f92ece2c9a9874d63634 in project qcacld-3.0) updated the only registrant to use the new interface. Now that the old interface is no longer being used, remove it. Change-Id: I32bb1f633b1dd1514aa6e4c3fdea044b3bca0009 CRs-Fixed: 2200971 --- core/src/wlan_tdls_cmds_process.c | 20 --------------- core/src/wlan_tdls_ct.c | 8 ------ core/src/wlan_tdls_main.h | 12 --------- dispatcher/inc/wlan_tdls_public_structs.h | 31 ----------------------- dispatcher/src/wlan_tdls_ucfg_api.c | 9 +------ 5 files changed, 1 insertion(+), 79 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 06f6813a6c..ffbc701f2d 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1501,7 +1501,6 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) id = wlan_vdev_get_id(vdev); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS if (TDLS_IS_LINK_CONNECTED(curr_peer)) { soc_obj->tdls_dereg_peer( soc_obj->tdls_peer_context, @@ -1513,19 +1512,6 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp) soc_obj->tdls_peer_context, id, curr_peer->sta_id); } -#else - if (TDLS_IS_LINK_CONNECTED(curr_peer)) { - soc_obj->tdls_dereg_tl_peer( - soc_obj->tdls_tl_peer_data, - id, curr_peer->sta_id); - tdls_decrement_peer_count(soc_obj); - } else if (TDLS_LINK_CONNECTING == - curr_peer->link_status) { - soc_obj->tdls_dereg_tl_peer( - soc_obj->tdls_tl_peer_data, - id, curr_peer->sta_id); - } -#endif } tdls_reset_peer(vdev_obj, macaddr); conn_rec[sta_idx].sta_id = 0; @@ -1697,15 +1683,9 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req) TDLS_LINK_SUCCESS); id = wlan_vdev_get_id(vdev); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS status = soc_obj->tdls_reg_peer(soc_obj->tdls_peer_context, id, mac, peer->sta_id, peer->qos); -#else - status = soc_obj->tdls_reg_tl_peer(soc_obj->tdls_tl_peer_data, - id, mac, peer->sta_id, - peer->signature, peer->qos); -#endif if (QDF_IS_STATUS_ERROR(status)) { tdls_err("TDLS register peer fail, status %d", status); goto error; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d6839a3e27..e2c73a49bd 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1274,19 +1274,11 @@ void tdls_disable_offchan_and_teardown_links( */ tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS if (tdls_soc->tdls_dereg_peer) tdls_soc->tdls_dereg_peer( tdls_soc->tdls_peer_context, wlan_vdev_get_id(vdev), curr_peer->sta_id); -#else - if (tdls_soc->tdls_dereg_tl_peer) - tdls_soc->tdls_dereg_tl_peer( - tdls_soc->tdls_tl_peer_data, - wlan_vdev_get_id(vdev), - curr_peer->sta_id); -#endif tdls_decrement_peer_count(tdls_soc); tdls_soc->tdls_conn_info[staidx].sta_id = 0; tdls_soc->tdls_conn_info[staidx].session_id = 255; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 14b2b65ca1..fbddfedc1c 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -170,15 +170,9 @@ struct tdls_set_state_info { * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data -#ifdef USE_NEW_TDLS_PEER_CALLBACKS * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath -#else - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer - * @tdls_reg_tl_peer: callback to register the TDLS peer with TL - * @tdls_dereg_tl_peer: callback to unregister the TDLS peer -#endif * @tx_q_ack: queue for tx frames waiting for ack * @tdls_con_cap: tdls concurrency support * @tdls_send_mgmt_req: store eWNI_SME_TDLS_SEND_MGMT_REQ value @@ -219,15 +213,9 @@ struct tdls_soc_priv_obj { void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; -#else - void *tdls_tl_peer_data; - tdls_register_tl_peer_callback tdls_reg_tl_peer; - tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; -#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; qdf_list_t tx_q_ack; enum tdls_conc_cap tdls_con_cap; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 0ada980ae6..4458872aaf 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -547,8 +547,6 @@ typedef void (*tdls_evt_callback) (void *data, typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, struct tdls_tx_cnf *tx_ack_cnf_cb_data); -#ifdef USE_NEW_TDLS_PEER_CALLBACKS - /* This callback is used to register TDLS peer with the datapath */ typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, uint32_t vdev_id, @@ -561,23 +559,6 @@ typedef QDF_STATUS (*tdls_deregister_peer_callback)(void *userdata, uint32_t vdev_id, uint8_t sta_id); -#else - -/* This callback is used to register TDLS peer with TL */ -typedef QDF_STATUS (*tdls_register_tl_peer_callback)(void *userdata, - uint32_t vdev_id, - const uint8_t *mac, - uint16_t stat_id, - uint8_t ucastsig, - uint8_t qos); - -/* This callback is used to deregister TDLS peer */ -typedef QDF_STATUS (*tdls_deregister_tl_peer_callback)(void *userdata, - uint32_t vdev_id, - uint8_t sta_id); - -#endif - /* This callback is used to update datapath vdev flags */ typedef QDF_STATUS (*tdls_dp_vdev_update_flags_callback)(void *cbk_data, @@ -598,15 +579,9 @@ typedef QDF_STATUS * @tdls_evt_cb_data: tdls event data * @ack_cnf_cb: tdls tx ack callback to indicate the tx status * @tx_ack_cnf_cb_data: tdls tx ack user data -#ifdef USE_NEW_TDLS_PEER_CALLBACKS * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath -#else - * @tdls_tl_peer_data: userdata for register/deregister TDLS peer - * @tdls_reg_tl_peer: tdls register tdls peer - * @tdls_dereg_tl_peer: tdls deregister tdls peer -#endif * @tdls_dp_vdev_update: update vdev flags in datapath */ struct tdls_start_params { @@ -625,15 +600,9 @@ struct tdls_start_params { void *tdls_evt_cb_data; tdls_tx_ack_cnf_callback ack_cnf_cb; void *tx_ack_cnf_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; -#else - void *tdls_tl_peer_data; - tdls_register_tl_peer_callback tdls_reg_tl_peer; - tdls_deregister_tl_peer_callback tdls_dereg_tl_peer; -#endif tdls_dp_vdev_update_flags_callback tdls_dp_vdev_update; }; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index f4aecc1502..9134509eac 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -207,17 +207,10 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; -#ifdef USE_NEW_TDLS_PEER_CALLBACKS - /* Save callbacks to register/deregister TDLS sta with TL */ + /* Save callbacks to register/deregister TDLS sta with datapath */ soc_obj->tdls_reg_peer = req->tdls_reg_peer; soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; soc_obj->tdls_peer_context = req->tdls_peer_context; -#else - /* Save callbacks to register/deregister TDLS sta with TL */ - soc_obj->tdls_reg_tl_peer = req->tdls_reg_tl_peer; - soc_obj->tdls_dereg_tl_peer = req->tdls_dereg_tl_peer; - soc_obj->tdls_tl_peer_data = req->tdls_tl_peer_data; -#endif /* Save legacy PE/WMA commands in TDLS soc object */ soc_obj->tdls_send_mgmt_req = req->tdls_send_mgmt_req; From 38dc9fe98dd5739a56ae3ddfb2d00b70d86212f9 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Fri, 2 Mar 2018 13:32:57 -0800 Subject: [PATCH 45/89] qcacmn: Remove obsolete TDLS signature Change "qcacmn: Remove obsolete TDLS peer callback interface" (Change-Id I32bb1f633b1dd1514aa6e4c3fdea044b3bca0009) removed the obsolete logic that utilized the TDLS signature field, so remove all remaining traces of it. Change-Id: I731c81a0b1f7e5d885cfa18a551ad0d3af3cecbe CRs-Fixed: 2200972 --- core/src/wlan_tdls_cmds_process.c | 4 ---- core/src/wlan_tdls_main.h | 2 -- core/src/wlan_tdls_peer.c | 15 --------------- core/src/wlan_tdls_peer.h | 15 +-------------- 4 files changed, 1 insertion(+), 35 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ffbc701f2d..9f9239c428 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1417,11 +1417,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) if (QDF_IS_STATUS_ERROR(status)) { tdls_err("set staid failed"); status = QDF_STATUS_E_FAILURE; - goto cmddone; } - - tdls_set_signature(vdev_obj, rsp->peermac.bytes, - rsp->ucast_sig); } else { status = QDF_STATUS_E_FAILURE; } diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index fbddfedc1c..6867ffd4f1 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -278,7 +278,6 @@ struct tdls_peer_mlme_info { * @rssi: rssi * @tdls_support: tdls support * @link_status: tdls link status - * @signature: signature * @is_responder: is responder * @discovery_processed: dicovery processed * @discovery_attempt: discovery attempt @@ -311,7 +310,6 @@ struct tdls_peer { int8_t rssi; enum tdls_peer_capab tdls_support; enum tdls_link_state link_status; - uint8_t signature; uint8_t is_responder; uint8_t discovery_processed; uint16_t discovery_attempt; diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index a254ff5fd3..998b4796a1 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -684,21 +684,6 @@ QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, return QDF_STATUS_SUCCESS; } -QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t signature) -{ - struct tdls_peer *peer; - - peer = tdls_find_peer(vdev_obj, macaddr); - if (!peer) { - tdls_err("peer is NULL"); - return QDF_STATUS_E_FAILURE; - } - peer->signature = signature; - - return QDF_STATUS_SUCCESS; -} - QDF_STATUS tdls_set_force_peer(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, bool forcepeer) { diff --git a/core/src/wlan_tdls_peer.h b/core/src/wlan_tdls_peer.h index 7a510c1dac..41ffa8096f 100644 --- a/core/src/wlan_tdls_peer.h +++ b/core/src/wlan_tdls_peer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -173,19 +173,6 @@ void tdls_set_peer_caps(struct tdls_vdev_priv_obj *vdev_obj, QDF_STATUS tdls_set_sta_id(struct tdls_vdev_priv_obj *vdev_obj, const uint8_t *macaddr, uint8_t sta_id); -/** - * tdls_set_signature() - set TDLS peer's signature - * @vdev_obj: TDLS vdev object - * @macaddr: MAC address of the TDLS peer - * @signature: signature value - * - * This is used in scheduler thread context, no lock required. - * - * Return: QDF_STATUS_SUCCESS if success; other values if failed - */ -QDF_STATUS tdls_set_signature(struct tdls_vdev_priv_obj *vdev_obj, - const uint8_t *macaddr, uint8_t signature); - /** * tdls_set_force_peer() - set/clear is_forced_peer flag on peer * @vdev_obj: TDLS vdev object From 8c2468e41e493ca81acf289d0e4282acedb52949 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Mon, 5 Mar 2018 12:06:17 -0800 Subject: [PATCH 46/89] qcacmn: Remove DPU signatures from TDLS Add STA Response The ucast_sig and bcast_sig fields in struct tdls_add_sta_rsp date back to a previous version of the driver that used these signatures to synchronize the data plane with the control plane. However the current version of the driver does not use these parameters, so remove them as the final stage of the plan to completely remove these signatures from throughout the driver. Since the converged struct tdls_add_sta_rsp must exactly match the legacy tSirTdlsAddStaRsp data structure, this change is co-dependent with the qcacld-3.0 change: qcacld-3.0: Remove DPU signatures from TDLS Add STA Response Change-Id: I765b090fc5dbe9bdaf83b05a72223c0a12f71a18 Change-Id: I7750fac9e4870d75358606bea427a5dbab97c665 CRs-Fixed: 2200973 --- core/src/wlan_tdls_cmds_process.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 10e20cfa1b..938e966716 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -140,8 +140,6 @@ struct tdls_add_sta_req { * @session_id: session id * @sta_id: sta id * @sta_type: sta type - * @ucast_sig: unicast signature - * @bcast_sig: broadcast signature * @tdls_oper: add peer type * @psoc: soc object */ @@ -153,8 +151,6 @@ struct tdls_add_sta_rsp { uint8_t session_id; uint16_t sta_id; uint16_t sta_type; - uint8_t ucast_sig; - uint8_t bcast_sig; enum tdls_add_oper tdls_oper; struct wlan_objmgr_psoc *psoc; }; From d7b52a1cc72f31297156feb8de38cc6492bd11b0 Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Wed, 28 Mar 2018 11:41:04 -0700 Subject: [PATCH 47/89] qcacmn: Use correct enum type in function call Use correct enum type in tdls_determine_channel_opclass, tdls_process_antenna_switch & tdls_process_send_mgmt_rsp. Change-Id: Idd4e7ac47196e3e11971fe3013805b6a8551c8de CRs-Fixed: 2214003 --- core/src/wlan_tdls_cmds_process.c | 6 ++++-- core/src/wlan_tdls_peer.c | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 9f9239c428..30bbe01e08 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1300,7 +1300,7 @@ QDF_STATUS tdls_process_send_mgmt_rsp(struct tdls_send_mgmt_rsp *rsp) if (tdls_soc && tdls_soc->tdls_event_cb) { ind.vdev = vdev; - ind.status = rsp->status_code; + ind.status = status; tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, TDLS_EVENT_MGMT_TX_ACK_CNF, &ind); } @@ -2276,7 +2276,9 @@ QDF_STATUS tdls_process_antenna_switch(struct tdls_antenna_switch_request *req) vdev_id = wlan_vdev_get_id(vdev); opmode = wlan_vdev_mlme_get_opmode(vdev); - channel = policy_mgr_get_channel(soc_obj->soc, opmode, &vdev_id); + channel = policy_mgr_get_channel(soc_obj->soc, + policy_mgr_convert_device_mode_to_qdf_type(opmode), + &vdev_id); /* Check supported nss for TDLS, if is 1x1, no need to teardown links */ if (WLAN_REG_IS_24GHZ_CH(channel)) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 998b4796a1..7e2f7e597b 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -397,7 +397,8 @@ static void tdls_determine_channel_opclass(struct tdls_soc_priv_obj *soc_obj, opmode = wlan_vdev_mlme_get_opmode(vdev_obj->vdev); *channel = policy_mgr_get_channel(soc_obj->soc, - opmode, &vdev_id); + policy_mgr_convert_device_mode_to_qdf_type(opmode), + &vdev_id); *opclass = 0; } else { *channel = peer->pref_off_chan_num; From e727d0d95d72a143ee443a8460ea24aedec9638a Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 29 Mar 2018 12:27:35 -0700 Subject: [PATCH 48/89] qcacmn: Fix compilation warnings in TDLS Fix the warning issue in TDLS, which popped up with newer compiler options. Change-Id: I1516a47ec01faa9315d2045ebcfe49097680e80d CRs-Fixed: 2215517 --- core/src/wlan_tdls_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index b271b3209a..00d31dad7d 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -284,7 +284,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( qdf_mem_copy(tdls_mgmt_req->peer_mac.bytes, action_req->tdls_mgmt.peer_mac.bytes, QDF_MAC_ADDR_SIZE); - if (action_req->tdls_mgmt.len && action_req->tdls_mgmt.buf) { + if (action_req->tdls_mgmt.len) { qdf_mem_copy(tdls_mgmt_req->add_ie, action_req->tdls_mgmt.buf, action_req->tdls_mgmt.len); } From 9098eacdc8c6a813049599824eba8a6231620ff8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Mon, 9 Apr 2018 16:08:22 -0700 Subject: [PATCH 49/89] qcacmn: Serialize TDLS set state cmd to firmware Serialize TDLS set command to firmware to avoid out of sequence WMI commands. Change-Id: Ia5d493b329dfa687e532797a5b47f3b82a0b3f76 CRs-Fixed: 2214605 --- core/src/wlan_tdls_main.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 782408f6d0..3917138491 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1108,7 +1108,9 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, uint32_t session_id) { + struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; + QDF_STATUS status; notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { @@ -1123,7 +1125,15 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify->vdev = vdev; notify->user_disconnect = false; - tdls_notify_sta_disconnect(notify); + msg.bodyptr = notify; + msg.callback = tdls_process_cmd; + msg.type = TDLS_NOTIFY_STA_DISCONNECTION; + + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(notify); + tdls_alert("message post failed "); + } } /** From 79d1442c3543780c36966378f81a9b3d9575fbfc Mon Sep 17 00:00:00 2001 From: Abhinav Kumar Date: Wed, 2 May 2018 15:42:54 +0530 Subject: [PATCH 50/89] qcacmn: Add break for few cases in tdls_process_mgmt_req Currently break statement is missing for some cases in tdls_process_mgmt_req. Add break statement as fallthrough is not required for these cases. Change-Id: I9ef290cdea8980f1b550cfebfb80ee81c5a694c0 CRs-Fixed: 2233184 --- core/src/wlan_tdls_mgmt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 00d31dad7d..38b93d1cab 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -417,6 +417,7 @@ QDF_STATUS tdls_process_mgmt_req( case WLAN_SER_CMD_DENIED_UNSPECIFIED: /* free the request */ qdf_mem_free(tdls_mgmt_req); + break; default: QDF_ASSERT(0); From de4df85fdbaa88fa300456a504f0bc5034bf2684 Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sun, 6 May 2018 11:21:59 -0700 Subject: [PATCH 51/89] qcacmn: Fix typo "adapater" Replace typo "adapater" with correct spelling "adapter". Change-Id: I53a98385a38df6e26fc3a4a5448566e89c6710ea CRs-Fixed: 2238309 --- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 4458872aaf..00fecd76da 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -186,7 +186,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SESSION_INCREMENT: notify session increment * @TDLS_CMD_SESSION_DECREMENT: notify session decrement * @TDLS_CMD_TEARDOWN_LINKS: notify teardown - * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapater reset + * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapter reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch */ From 65059eb8372a9c22ebc576630073e64e88303abd Mon Sep 17 00:00:00 2001 From: Jeff Johnson Date: Sat, 12 May 2018 13:22:27 -0700 Subject: [PATCH 52/89] qcacmn: umac: Fix misspellings Address the following issues in the umac folder: CHECK: 'defintions' may be misspelled - perhaps 'definitions'? CHECK: 'destory' may be misspelled - perhaps 'destroy'? CHECK: 'faild' may be misspelled - perhaps 'failed'? CHECK: 'initilization' may be misspelled - perhaps 'initialization'? CHECK: 'managment' may be misspelled - perhaps 'management'? CHECK: 'muticast' may be misspelled - perhaps 'multicast'? CHECK: 'ouput' may be misspelled - perhaps 'output'? CHECK: 'segement' may be misspelled - perhaps 'segment'? CHECK: 'successfull' may be misspelled - perhaps 'successful'? CHECK: 'untill' may be misspelled - perhaps 'until'? Change-Id: If60c276c134ef10ce6be26cd5a4036d53d5724b6 CRs-Fixed: 2241586 --- core/src/wlan_tdls_ct.h | 6 +++--- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- dispatcher/inc/wlan_tdls_ucfg_api.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index b713c971b4..04926b9bba 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -60,7 +60,7 @@ void tdls_implicit_enable(struct tdls_vdev_priv_obj *tdls_vdev); * @mac_addr: mac address of the data * * Increase the rx packet count, if the sender is not bssid and the packet is - * not broadcast and muticast packet + * not broadcast and multicast packet * * This sampling information will be used in TDLS connection tracker * @@ -78,7 +78,7 @@ void tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, * @mac_addr: mac address of the data * * Increase the tx packet count, if the sender is not bssid and the packet is - * not broadcast and muticast packet + * not broadcast and multicast packet * * This sampling information will be used in TDLS connection tracker * diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 00fecd76da..089a75f9e1 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1007,7 +1007,7 @@ struct tdls_get_all_peers { * @cmd_buf: cmd buffer * @len: length of the frame * @use_default_ac: access category - * @tdls_mgmt: tdls managment + * @tdls_mgmt: tdls management */ struct tdls_action_frame_request { struct wlan_objmgr_vdev *vdev; diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index ffe3404dc6..1135c48e2d 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -40,7 +40,7 @@ QDF_STATUS ucfg_tdls_init(void); /** - * ucfg_tdls_deinit() - TDLS module deinitilization API + * ucfg_tdls_deinit() - TDLS module deinitialization API * * Return: QDF_STATUS */ From 618adb809f112b626b973c51ca4dc4f85e8eabdd Mon Sep 17 00:00:00 2001 From: Tushnim Bhattacharyya Date: Fri, 1 Jun 2018 15:16:53 -0700 Subject: [PATCH 53/89] qcacmn: Reduce log level to debug for tdls Reduce the log level for tdls related logs from info to debug. Change-Id: I0de4d0b4ae78a5b1c72c975d4d928cee7c21970f CRs-Fixed: 2252980 --- core/src/wlan_tdls_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 3917138491..e4406818a3 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -1338,7 +1338,7 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) if (TDLS_SUPPORT_IMP_MODE == tdls_soc->tdls_last_mode || TDLS_SUPPORT_EXT_CONTROL == tdls_soc->tdls_last_mode || TDLS_SUPPORT_EXP_TRIG_ONLY == tdls_soc->tdls_last_mode) { - tdls_notice("revert tdls mode %d", + tdls_debug("revert tdls mode %d", tdls_soc->tdls_last_mode); tdls_set_current_mode(tdls_soc, tdls_soc->tdls_last_mode, From 2688ed785defce0bed78a9e165ff7520102535e7 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 24 Apr 2018 16:50:40 +0800 Subject: [PATCH 54/89] qcacmn: Reject tdls_vdev create/destroy when disabled in INI Reject tdls_vdev creation and destroy, when TDLS is disabled in INI. Change-Id: Ie85e8ed231e14dc413e4bfdcff205c47115c84dd CRs-Fixed: 2229872 --- core/src/wlan_tdls_main.c | 49 ++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e4406818a3..e1a564ce92 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -150,13 +150,26 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, QDF_STATUS status; struct tdls_vdev_priv_obj *tdls_vdev_obj; struct wlan_objmgr_pdev *pdev; - struct tdls_soc_priv_obj *tdls_soc; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint32_t tdls_feature_flags; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc_obj) { + tdls_err("get soc by vdev failed"); + return QDF_STATUS_E_NOMEM; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("disabled in ini"); + return QDF_STATUS_E_NOSUPPORT; + } + /* TODO: Add concurrency check */ tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); @@ -171,33 +184,29 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, QDF_STATUS_SUCCESS); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach vdev tdls component"); - qdf_mem_free(tdls_vdev_obj); - goto out; + goto err; } tdls_vdev_obj->vdev = vdev; status = tdls_vdev_init(tdls_vdev_obj); if (QDF_IS_STATUS_ERROR(status)) - goto out; - - tdls_soc = wlan_vdev_get_tdls_soc_obj(vdev); - if (!tdls_soc) { - tdls_err("get soc by vdev failed "); - return QDF_STATUS_E_NOMEM; - } + goto err; pdev = wlan_vdev_get_pdev(vdev); status = ucfg_scan_register_event_handler(pdev, tdls_scan_complete_event_handler, - tdls_soc); + tdls_soc_obj); if (QDF_STATUS_SUCCESS != status) { tdls_err("scan event register failed "); - return QDF_STATUS_E_FAILURE; + tdls_vdev_deinit(tdls_vdev_obj); + goto err; } tdls_notice("tdls object attach to vdev successfully"); -out: + return status; +err: + qdf_mem_free(tdls_vdev_obj); return status; } @@ -206,12 +215,26 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, { QDF_STATUS status; void *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + uint32_t tdls_feature_flags; tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(vdev); + if (!tdls_soc_obj) { + tdls_err("get soc by vdev failed"); + return QDF_STATUS_E_NOMEM; + } + + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("disabled in ini"); + return QDF_STATUS_E_NOSUPPORT; + } + tdls_vdev_obj = wlan_objmgr_vdev_get_comp_private_obj(vdev, WLAN_UMAC_COMP_TDLS); if (!tdls_vdev_obj) { From 5ff88a8b637f5dcf2e2280b4ed0ed303130806e8 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Sun, 13 May 2018 20:12:37 -0700 Subject: [PATCH 55/89] qcacmn: Remove unused data structures in TDLS component Remove the unused data structures in TDLS component to avoid incorrect usage Change-Id: Id3997d5895dba8e3cb3f60fe102ca846cb009607 CRs-Fixed: 2232726 --- core/src/wlan_tdls_main.h | 4 ---- dispatcher/inc/wlan_tdls_public_structs.h | 8 -------- dispatcher/src/wlan_tdls_ucfg_api.c | 6 ------ 3 files changed, 18 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 6867ffd4f1..b2a0a86137 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -165,9 +165,7 @@ struct tdls_set_state_info { * @tdls_nss_teardown_complete: tdls tear down complete * @tdls_nss_transition_mode: tdls nss transition mode * @tdls_teardown_peers_cnt: tdls tear down peer count - * @tdls_tx_cnf_cb: callback registered by hdd to receive the ack cnf * @set_state_info: set tdls state info - * @tx_ack_cnf_cb_data: user data to tdls_tx_cnf_cb * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event user data * @tdls_peer_context: userdata for register/deregister TDLS peer @@ -209,8 +207,6 @@ struct tdls_soc_priv_obj { void *tdls_rx_cb_data; tdls_wmm_check tdls_wmm_cb; void *tdls_wmm_cb_data; - tdls_tx_ack_cnf_callback tdls_tx_cnf_cb; - void *tx_ack_cnf_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; void *tdls_peer_context; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 089a75f9e1..8f1e045fb9 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -543,10 +543,6 @@ typedef void (*tdls_evt_callback) (void *data, enum tdls_event_type ev_type, struct tdls_osif_indication *event); -/* prototype of callback registered by hdd to receive the ack cnf */ -typedef int (*tdls_tx_ack_cnf_callback)(void *user_data, - struct tdls_tx_cnf *tx_ack_cnf_cb_data); - /* This callback is used to register TDLS peer with the datapath */ typedef QDF_STATUS (*tdls_register_peer_callback)(void *userdata, uint32_t vdev_id, @@ -577,8 +573,6 @@ typedef QDF_STATUS * @tdls_update_dp_vdev_flags: pass CDP_UPDATE_TDLS_FLAGS * @tdls_event_cb: tdls event callback * @tdls_evt_cb_data: tdls event data - * @ack_cnf_cb: tdls tx ack callback to indicate the tx status - * @tx_ack_cnf_cb_data: tdls tx ack user data * @tdls_peer_context: userdata for register/deregister TDLS peer * @tdls_reg_peer: register tdls peer with datapath * @tdls_dereg_peer: deregister tdls peer from datapath @@ -598,8 +592,6 @@ struct tdls_start_params { void *tdls_wmm_cb_data; tdls_evt_callback tdls_event_cb; void *tdls_evt_cb_data; - tdls_tx_ack_cnf_callback ack_cnf_cb; - void *tx_ack_cnf_cb_data; void *tdls_peer_context; tdls_register_peer_callback tdls_reg_peer; tdls_deregister_peer_callback tdls_dereg_peer; diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 9134509eac..d071dc0cd6 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -204,9 +204,6 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, soc_obj->tdls_event_cb = req->tdls_event_cb; soc_obj->tdls_evt_cb_data = req->tdls_evt_cb_data; - soc_obj->tdls_tx_cnf_cb = req->ack_cnf_cb; - soc_obj->tx_ack_cnf_cb_data = req->tx_ack_cnf_cb_data; - /* Save callbacks to register/deregister TDLS sta with datapath */ soc_obj->tdls_reg_peer = req->tdls_reg_peer; soc_obj->tdls_dereg_peer = req->tdls_dereg_peer; @@ -307,9 +304,6 @@ QDF_STATUS ucfg_tdls_psoc_disable(struct wlan_objmgr_psoc *psoc) soc_obj->tdls_event_cb = NULL; soc_obj->tdls_evt_cb_data = NULL; - soc_obj->tdls_tx_cnf_cb = NULL; - soc_obj->tx_ack_cnf_cb_data = NULL; - return status; } From b02882e70b24a4162d668e906675c0a39432e9eb Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 5 Jun 2018 16:24:14 +0530 Subject: [PATCH 56/89] qcacmn: Fix TDLS tear down issue on initiator The tdls peer sta id is allocated as part of wma_create_peer. In HDD, as part of change interface, wlan_hdd_tdls_disable_offchan_and_teardown_links API is called. Here driver checks for valid TDLS peers based on staid. Here HDD assumes staid zero as invalid and non zero values as valid ID. This is not correct as staid zero also is a valid staid. Due to this teardown status is not informed to upper layers. Use 0xFF as invalid sta id for tdls peer to fix this issue. Change-Id: I3827df9a63081952b2d443c175ef5a59eab85e43 CRs-Fixed: 2258171 --- core/src/wlan_tdls_cmds_process.c | 6 +++--- core/src/wlan_tdls_ct.c | 7 ++++--- core/src/wlan_tdls_peer.c | 2 +- dispatcher/inc/wlan_tdls_public_structs.h | 3 ++- dispatcher/src/wlan_tdls_ucfg_api.c | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 30bbe01e08..8570484c2d 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1398,7 +1398,7 @@ static QDF_STATUS tdls_add_peer_rsp(struct tdls_add_sta_rsp *rsp) conn_rec = soc_obj->tdls_conn_info; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - if (0 == conn_rec[sta_idx].sta_id) { + 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; qdf_copy_macaddr(&conn_rec[sta_idx].peer_mac, @@ -1510,7 +1510,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 = 0; + conn_rec[sta_idx].sta_id = INVALID_TDLS_PEER_ID; conn_rec[sta_idx].session_id = 0xff; qdf_mem_zero(&conn_rec[sta_idx].peer_mac, QDF_MAC_ADDR_SIZE); @@ -2190,7 +2190,7 @@ static int tdls_teardown_links(struct tdls_soc_priv_obj *soc_obj, uint32_t mode) conn_rec = soc_obj->tdls_conn_info; for (staidx = 0; staidx < soc_obj->max_num_tdls_sta; staidx++) { - if (conn_rec[staidx].sta_id == 0) + if (conn_rec[staidx].sta_id == INVALID_TDLS_PEER_ID) continue; curr_peer = tdls_find_all_peer(soc_obj, diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e2c73a49bd..7c44278af4 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -587,7 +587,7 @@ tdls_ct_process_idle_handler( &tdls_soc_obj)) return; - if (!tdls_info->sta_id) { + if (INVALID_TDLS_PEER_ID == tdls_info->sta_id) { tdls_err("peer (staidx %u) doesn't exists", tdls_info->sta_id); return; } @@ -1252,7 +1252,8 @@ void tdls_disable_offchan_and_teardown_links( for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; staidx++) { - if (!tdls_soc->tdls_conn_info[staidx].sta_id) + if (tdls_soc->tdls_conn_info[staidx].sta_id + == INVALID_TDLS_PEER_ID) continue; curr_peer = tdls_find_all_peer(tdls_soc, @@ -1280,7 +1281,7 @@ void tdls_disable_offchan_and_teardown_links( wlan_vdev_get_id(vdev), curr_peer->sta_id); tdls_decrement_peer_count(tdls_soc); - tdls_soc->tdls_conn_info[staidx].sta_id = 0; + tdls_soc->tdls_conn_info[staidx].sta_id = INVALID_TDLS_PEER_ID; tdls_soc->tdls_conn_info[staidx].session_id = 255; qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 7e2f7e597b..b761646d0c 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -756,7 +756,7 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj, tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE, TDLS_LINK_UNSPECIFIED); - curr_peer->sta_id = 0; + curr_peer->sta_id = INVALID_TDLS_PEER_ID; return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 8f1e045fb9..cb5a8f816e 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -74,8 +74,9 @@ #define TDLS_TEARDOWN_PEER_UNREACHABLE 25 #define TDLS_TEARDOWN_PEER_UNSPEC_REASON 26 +#define INVALID_TDLS_PEER_ID 0xFF #define TDLS_STA_INDEX_CHECK(sta_id) \ - (((sta_id) >= 1) && ((sta_id) < 0xFF)) + (((sta_id) >= 0) && ((sta_id) < 0xFF)) /** * enum tdls_conc_cap - tdls concurrency support * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index d071dc0cd6..442fb5c9f9 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -137,7 +137,7 @@ static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) soc_obj->max_num_tdls_sta = WLAN_TDLS_STA_MAX_NUM; for (sta_idx = 0; sta_idx < soc_obj->max_num_tdls_sta; sta_idx++) { - soc_obj->tdls_conn_info[sta_idx].sta_id = 0; + soc_obj->tdls_conn_info[sta_idx].sta_id = INVALID_TDLS_PEER_ID; 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); From 1554dcd7e143e2caa9530bf67e66891ea93857c2 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Thu, 12 Apr 2018 17:38:28 -0700 Subject: [PATCH 57/89] qcacmn: Do not stop TDLS timers before restart MC timer implementation has changed recently, and it requires TDLS timers shouldn't be stopped before restart. Change-Id: I718972bd0f7c66b04145ee38c58440f6240a8de2 CRs-Fixed: 2223777 --- core/src/wlan_tdls_main.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index e1a564ce92..852352255e 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -374,7 +374,6 @@ void tdls_timer_restart(struct wlan_objmgr_vdev *vdev, qdf_mc_timer_t *timer, uint32_t expiration_time) { - qdf_mc_timer_stop(timer); qdf_mc_timer_start(timer, expiration_time); } From ce724ff735f56ae1960382bc76be2d19db6c6e85 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Tue, 26 Jun 2018 15:21:30 +0800 Subject: [PATCH 58/89] qcacmn: Initialize tdls peer sta_id TDLS sta_id check logic has changed, the value zero is valid, so initialize the tdls peer sta_id as 0xff, otherwise add tdls peer won't happen. Change-Id: I805e4abdec8806f649d15da4f02980de9ffdc0ea CRs-Fixed: 2263523 --- core/src/wlan_tdls_peer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index b761646d0c..82ecb43d32 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -185,6 +185,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj, tdls_find_opclass(soc_obj->soc, peer->pref_off_chan_num, soc_obj->tdls_configs.tdls_pre_off_chan_bw); + peer->sta_id = INVALID_TDLS_PEER_ID; qdf_list_insert_back(head, &peer->node); From dcff88fc76c1d53289788f9a5a9a607ac3ce78ab Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 29 Jun 2018 11:58:08 +0800 Subject: [PATCH 59/89] qcacmn: Post tdls connet/disconnect event to target_if queue TDLS will update tdls firmware state according to STA connection status, the change is to post tdls connect/disconnect event to target_if queue, otherwise these events will be scheduled too late which would be out of sync, cause unexpected results. Change-Id: I76d70339f236b580bfb98fb1b8f5121784cb3465 CRs-Fixed: 2269978 --- dispatcher/src/wlan_tdls_ucfg_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 442fb5c9f9..c93333d99e 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -636,7 +636,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); return QDF_STATUS_SUCCESS; @@ -669,7 +669,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); From e173405103640123e9f5fffad687fcdf3e71cd05 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 28 Jun 2018 11:13:25 +0530 Subject: [PATCH 60/89] qcacmn: Avoid possible buffer overflow In function tdls_ct_sampling_tx_rx, memcpy of unknown length buffer is done into fixed size struct array. Mem copying without checking length can lead to buffer overflow. Change-Id: I0608bd69d71ff1901f82b44d045963e9d383e6ce CRs-Fixed: 2269276 --- core/src/wlan_tdls_ct.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 7c44278af4..b3f28a4586 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -223,7 +223,8 @@ static void tdls_ct_sampling_tx_rx(struct tdls_vdev_priv_obj *tdls_vdev, return; } - mac_entries = tdls_vdev->valid_mac_entries; + mac_entries = QDF_MIN(tdls_vdev->valid_mac_entries, + WLAN_TDLS_CT_TABLE_SIZE); qdf_mem_copy(mac_table, tdls_vdev->ct_peer_table, (sizeof(struct tdls_conn_tracker_mac_table)) * mac_entries); From 693754cc10d23c9b121bb15dded2d36869fdd28f Mon Sep 17 00:00:00 2001 From: Kiran Kumar Lokere Date: Tue, 15 May 2018 15:48:57 -0700 Subject: [PATCH 61/89] qcacmn: Add support for SRD channels in ETSI domain Add support for Short Range Devices 25 mW max power channels in ETSI regulatory domain. Add Short Range Devices 25 mW max power channels only if DSRC feature is disabled. Provide service apis to check SRD and DSRC channels. Change-Id: Ib2a1d7cf191d07319cb29038ad60130f5cbe7f16 CRs-Fixed: 2264790 --- core/src/wlan_tdls_peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 82ecb43d32..3f8a132e0e 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -515,7 +515,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, if (CHANNEL_STATE_INVALID != ch_state && CHANNEL_STATE_DFS != ch_state && - !wlan_is_dsrc_channel(wlan_is_dsrc_channel(chan_id))) { + !wlan_reg_is_dsrc_chan(pdev, chan_id)) { peer_param->peer_cap.peer_chan[num].chan_id = chan_id; peer_param->peer_cap.peer_chan[num].pwr = wlan_reg_get_channel_reg_power(pdev, chan_id); From 0bbf3364757a83ced2574ea7c15abb9343fdf094 Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Sat, 23 Jun 2018 14:43:23 +0530 Subject: [PATCH 62/89] qcacmn: Map all module logs to per-level log APIs Map all module level log APIs to per-level log APIs to compile out specific log level if required. Change-Id: I4072b6740cb43200fd95c40943b66e1d5f8f1847 CRs-Fixed: 2266719 --- core/src/wlan_tdls_main.h | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index b2a0a86137..d9cd88864d 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -57,22 +57,16 @@ #define TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE 1000 #define TDLS_SCAN_REJECT_MAX 5 - -#define tdls_log(level, args...) \ - QDF_TRACE(QDF_MODULE_ID_TDLS, level, ## args) -#define tdls_logfl(level, format, args...) \ - tdls_log(level, FL(format), ## args) - -#define tdls_debug(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_DEBUG, format, ## args) -#define tdls_notice(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_INFO, format, ## args) -#define tdls_warn(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_WARN, format, ## args) -#define tdls_err(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_ERROR, format, ## args) -#define tdls_alert(format, args...) \ - tdls_logfl(QDF_TRACE_LEVEL_FATAL, format, ## args) +#define tdls_debug(params...) \ + QDF_TRACE_DEBUG(QDF_MODULE_ID_TDLS, params) +#define tdls_notice(params...) \ + QDF_TRACE_INFO(QDF_MODULE_ID_TDLS, params) +#define tdls_warn(params...) \ + QDF_TRACE_WARN(QDF_MODULE_ID_TDLS, params) +#define tdls_err(params...) \ + QDF_TRACE_ERROR(QDF_MODULE_ID_TDLS, params) +#define tdls_alert(params...) \ + QDF_TRACE_FATAL(QDF_MODULE_ID_TDLS, params) #define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ From a551f698df5a6786846dcde329d35c45d5a78133 Mon Sep 17 00:00:00 2001 From: Jingxiang Ge Date: Fri, 13 Jul 2018 15:16:03 +0800 Subject: [PATCH 63/89] qcacmn: Fix use after free for vdev in tdls When disconnect happens, TDLS_NOTIFY_STA_DISCONNECTION will be send to scheduler_thread, in bad case, it is processed after 3s later, and the vdev passed in notify msg has been freed in the period, invalid vdev causes invalid memory access. change as below: 1.1 Get vdev ref before send msg 1.2 register callback for release ref 1.3 send msg to scheduler_thread 1.4 process tdls notify msg and call callback function. Change-Id: I2b03db8b30db623796f2e8299f14ee31e28efb91 CRs-Fixed: 2275019 --- core/src/wlan_tdls_main.c | 41 +++++++++-------------- core/src/wlan_tdls_main.h | 9 +++-- dispatcher/inc/wlan_tdls_public_structs.h | 4 +++ dispatcher/src/wlan_tdls_tgt_api.c | 29 +++++++++++++--- dispatcher/src/wlan_tdls_ucfg_api.c | 13 ++----- 5 files changed, 51 insertions(+), 45 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 852352255e..bd1a2783f0 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -901,19 +901,16 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) { QDF_STATUS status; - if (!notify || !notify->vdev) - return QDF_STATUS_E_INVAL; - - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) { - qdf_mem_free(notify); + if (!notify || !notify->vdev) { + tdls_err("invalid param"); return QDF_STATUS_E_INVAL; } status = tdls_process_sta_connect(notify); - wlan_objmgr_vdev_release_ref(notify->vdev, - WLAN_TDLS_NB_ID); + if (notify->callback) + notify->callback(notify->vdev); + qdf_mem_free(notify); return status; } @@ -993,19 +990,15 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) { QDF_STATUS status; - if (!notify || !notify->vdev) - return QDF_STATUS_E_INVAL; - - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) { - qdf_mem_free(notify); + if (!notify || !notify->vdev) { + tdls_err("invalid param"); return QDF_STATUS_E_INVAL; } status = tdls_process_sta_disconnect(notify); - wlan_objmgr_vdev_release_ref(notify->vdev, - WLAN_TDLS_NB_ID); + if (notify->callback) + notify->callback(notify->vdev); qdf_mem_free(notify); return status; @@ -1127,8 +1120,8 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); } -void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, - uint32_t session_id) +QDF_STATUS tdls_peers_deleted_notification( + struct tdls_sta_notify_params *notify_info) { struct scheduler_msg msg = {0, }; struct tdls_sta_notify_params *notify; @@ -1137,15 +1130,10 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { tdls_err("memory allocation failed !!!"); - return; + return QDF_STATUS_E_NULL_VALUE; } - notify->lfr_roam = true; - notify->tdls_chan_swit_prohibited = false; - notify->tdls_prohibited = false; - notify->session_id = session_id; - notify->vdev = vdev; - notify->user_disconnect = false; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; @@ -1155,7 +1143,10 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(notify); tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; } + + return QDF_STATUS_SUCCESS; } /** diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index d9cd88864d..5c6591424b 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -584,17 +584,16 @@ void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev); /** * tdls_peers_deleted_notification() - peer delete notification - * @vdev: vdev object - * @session_id: session id + * @notify_info: peer info * * 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. * state. * - * Return: None + * Return: QDF_STATUS */ -void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, - uint32_t session_id); +QDF_STATUS tdls_peers_deleted_notification( + struct tdls_sta_notify_params *notify_info); /** * tdls_notify_decrement_session() - Notify the session decrement diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index cb5a8f816e..eec7260b5d 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -563,6 +563,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); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1041,6 +1044,7 @@ struct tdls_sta_notify_params { bool lfr_roam; bool user_disconnect; uint8_t session_id; + tdls_sta_notify_callback callback; }; /** diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index c89e202e20..5c58a73361 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -329,10 +329,23 @@ 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) { 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, @@ -344,9 +357,17 @@ void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, return; } - tdls_peers_deleted_notification(vdev, session_id); - - wlan_objmgr_vdev_release_ref(vdev, - WLAN_TDLS_SB_ID); + 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); + } } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index c93333d99e..a477ac60ef 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -627,11 +627,7 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( if (!notify) return QDF_STATUS_E_NULL_VALUE; - notify->session_id = notify_info->session_id; - notify->tdls_chan_swit_prohibited = - notify_info->tdls_chan_swit_prohibited; - notify->tdls_prohibited = notify_info->tdls_prohibited; - notify->vdev = notify_info->vdev; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; @@ -659,12 +655,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( if (!notify) return QDF_STATUS_E_NULL_VALUE; - notify->session_id = notify_info->session_id; - notify->tdls_chan_swit_prohibited = false; - notify->tdls_prohibited = false; - notify->vdev = notify_info->vdev; - notify->lfr_roam = notify_info->lfr_roam; - notify->user_disconnect = notify_info->user_disconnect; + *notify = *notify_info; msg.bodyptr = notify; msg.callback = tdls_process_cmd; From 3baf0037227c4b99046fa5d0ea33f5814048223d Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Tue, 19 Jun 2018 19:21:06 +0800 Subject: [PATCH 64/89] qcacmn: Define configures about TDLS Based on converged cfg component, define TDLS configures and APIs to get or set these configures. Change-Id: I86f61246b810c7f25a74c814df20d0e2c810b292 CRs-Fixed: 2277559 --- dispatcher/inc/wlan_tdls_cfg.h | 759 ++++++++++++++++++++++ dispatcher/inc/wlan_tdls_cfg_api.h | 217 +++++++ dispatcher/inc/wlan_tdls_public_structs.h | 20 +- dispatcher/src/wlan_tdls_cfg.c | 324 +++++++++ dispatcher/src/wlan_tdls_ucfg_api.c | 97 ++- 5 files changed, 1413 insertions(+), 4 deletions(-) create mode 100644 dispatcher/inc/wlan_tdls_cfg.h create mode 100644 dispatcher/inc/wlan_tdls_cfg_api.h create mode 100644 dispatcher/src/wlan_tdls_cfg.c diff --git a/dispatcher/inc/wlan_tdls_cfg.h b/dispatcher/inc/wlan_tdls_cfg.h new file mode 100644 index 0000000000..03827e593a --- /dev/null +++ b/dispatcher/inc/wlan_tdls_cfg.h @@ -0,0 +1,759 @@ +/* + * Copyright (c) 2018 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#if !defined(CONFIG_TDLS_H__) +#define CONFIG_TDLS_H__ + +#include "cfg_define.h" +#include "cfg_converged.h" +#include "qdf_types.h" + +/* + * + * gTDLSUapsdMask - ACs to setup U-APSD for TDLS Sta. + * @Min: 0 + * @Max: 0x0F + * @Default: 0x0F + * + * This ini is used to configure the ACs for which mask needs to be enabled. + * 0x1: Background 0x2: Best effort + * 0x4: Video 0x8: Voice + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_QOS_WMM_UAPSD_MASK CFG_INI_UINT( \ + "gTDLSUapsdMask", \ + 0, \ + 0x0F, \ + 0x0F, \ + CFG_VALUE_OR_DEFAULT, \ + "ACs to setup U-APSD for TDLS Sta") + +/* + * + * gEnableTDLSBufferSta - Controls the TDLS buffer. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to control the TDLS buffer. + * Buffer STA is not enabled in CLD 2.0 yet. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_BUF_STA_ENABLED CFG_INI_BOOL( \ + "gEnableTDLSBufferSta", \ + 1, \ + "Controls the TDLS buffer") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_INACT_TIME CFG_INI_UINT( \ + "gTDLSPuapsdInactivityTime", \ + 0, \ + 10, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Inactivity time") + +/* + * + * gTDLSPuapsdRxFrameThreshold - Peer UAPSD Rx frame threshold. + * @Min: 10 + * @Max: 20 + * @Default: 10 + * + * This ini is used to configure maximum Rx frame during SP. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RX_FRAME_THRESHOLD CFG_INI_UINT( \ + "gTDLSPuapsdRxFrameThreshold", \ + 10, \ + 20, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Rx frame threshold") + +/* + * + * gEnableTDLSOffChannel - Enables off-channel support for TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable off-channel support for TDLS link. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_OFF_CHANNEL_ENABLED CFG_INI_BOOL( \ + "gEnableTDLSOffChannel", \ + 0, \ + "Enables off-channel support for TDLS") + +/* + * + * gEnableTDLSSupport - Enable support for TDLS. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable TDLS support. + * + * Related: None. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_SUPPORT_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSSupport", \ + 0, \ + "enable/disable TDLS support") + +/* + * + * gEnableTDLSImplicitTrigger - Enable Implicit TDLS. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable implicit TDLS. + * CLD driver initiates TDLS Discovery towards a peer whenever TDLS Setup + * criteria (throughput and RSSI thresholds) is met and then it tears down + * TDLS when teardown criteria (idle packet count and RSSI) is met. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_IMPLICIT_TRIGGER CFG_INI_BOOL( \ + "gEnableTDLSImplicitTrigger", \ + 0, \ + "enable/disable implicit TDLS") + +/* + * + * gTDLSTxStatsPeriod - TDLS TX statistics time period. + * @Min: 1000 + * @Max: 4294967295 + * @Default: 2000 + * + * This ini is used to configure the time period (in ms) to evaluate whether + * the number of Tx/Rx packets exceeds TDLSTxPacketThreshold and triggers a + * TDLS Discovery request. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_TX_STATS_PERIOD CFG_INI_UINT( \ + "gTDLSTxStatsPeriod", \ + 1000, \ + 4294967295UL, \ + 2000, \ + CFG_VALUE_OR_DEFAULT, \ + "TDLS TX statistics time period") + +/* + * + * gTDLSTxPacketThreshold - Tx/Rx Packet threshold for initiating TDLS. + * @Min: 0 + * @Max: 4294967295 + * @Default: 40 + * + * This ini is used to configure the number of Tx/Rx packets during the + * period of gTDLSTxStatsPeriod when exceeded, a TDLS Discovery request + * is triggered. + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_TX_PACKET_THRESHOLD CFG_INI_UINT( \ + "gTDLSTxPacketThreshold", \ + 0, \ + 4294967295UL, \ + 40, \ + CFG_VALUE_OR_DEFAULT, \ + "Tx/Rx Packet threshold for initiating TDLS") + +/* + * + * gTDLSMaxDiscoveryAttempt - Attempts for sending TDLS discovery requests. + * @Min: 1 + * @Max: 100 + * @Default: 5 + * + * This ini is used to configure the number of failures of discover request, + * when exceeded, the peer is assumed to be not TDLS capable and no further + * TDLS Discovery request is made. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_MAX_DISCOVERY_ATTEMPT CFG_INI_UINT( \ + "gTDLSMaxDiscoveryAttempt", \ + 1, \ + 100, \ + 5, \ + CFG_VALUE_OR_DEFAULT, \ + "Attempts for sending TDLS discovery requests") + +/* + * + * gTDLSIdleTimeout - Duration within which number of TX / RX frames meet the + * criteria for TDLS teardown. + * @Min: 500 + * @Max: 40000 + * @Default: 5000 + * + * This ini is used to configure the time period (in ms) to evaluate whether + * the number of Tx/Rx packets exceeds gTDLSIdlePacketThreshold and thus meets + * criteria for TDLS teardown. + * Teardown notification interval (gTDLSIdleTimeout) should be multiple of + * setup notification (gTDLSTxStatsPeriod) interval. + * e.g. + * if setup notification (gTDLSTxStatsPeriod) interval = 500, then + * teardown notification (gTDLSIdleTimeout) interval should be 1000, + * 1500, 2000, 2500... + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + */ +#define CFG_TDLS_IDLE_TIMEOUT CFG_INI_UINT( \ + "gTDLSIdleTimeout", \ + 500, \ + 40000, \ + 5000, \ + CFG_VALUE_OR_DEFAULT, \ + "this is idle time period") + +/* + * + * gTDLSIdlePacketThreshold - Number of idle packet. + * @Min: 0 + * @Max: 40000 + * @Default: 3 + * + * This ini is used to configure the number of Tx/Rx packet, below which + * within last gTDLSTxStatsPeriod period is considered as idle condition. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_IDLE_PACKET_THRESHOLD CFG_INI_UINT( \ + "gTDLSIdlePacketThreshold", \ + 0, \ + 40000, \ + 3, \ + CFG_VALUE_OR_DEFAULT, \ + "Number of idle packet") + +/* + * + * gTDLSRSSITriggerThreshold - RSSI threshold for TDLS connection. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * below which a TDLS setup request is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_TRIGGER_THRESHOLD CFG_INI_INT( \ + "gTDLSRSSITriggerThreshold", \ + -120, \ + 0, \ + -75, \ + CFG_VALUE_OR_DEFAULT, \ + "RSSI threshold for TDLS connection") + +/* + * + * gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * when exceed, a TDLS teardown is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_TEARDOWN_THRESHOLD CFG_INI_INT( \ + "gTDLSRSSITeardownThreshold", \ + -120, \ + 0, \ + -75, \ + CFG_VALUE_OR_DEFAULT, \ + "RSSI threshold for TDLS teardown") + +/* + * + * gTDLSRSSITeardownThreshold - RSSI threshold for TDLS teardown. + * @Min: -120 + * @Max: 0 + * @Default: -75 + * + * This ini is used to configure the absolute value (in dB) of the peer RSSI, + * when exceed, a TDLS teardown is triggered. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_RSSI_DELTA CFG_INI_INT( \ + "gTDLSRSSIDelta", \ + -30, \ + 0, \ + -20, \ + CFG_VALUE_OR_DEFAULT, \ + "Delta value for the peer RSSI that can trigger teardown") + +/* + * + * gTDLSPrefOffChanNum - Preferred TDLS channel number when off-channel support + * is enabled. + * @Min: 1 + * @Max: 165 + * @Default: 36 + * + * This ini is used to configure preferred TDLS channel number when off-channel + * support is enabled. + * + * Related: gEnableTDLSSupport, gEnableTDLSOffChannel. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM CFG_INI_UINT( \ + "gTDLSPrefOffChanNum", \ + 1, \ + 165, \ + 36, \ + CFG_VALUE_OR_DEFAULT, \ + "Preferred TDLS channel number") + +/* + * + * gTDLSPrefOffChanBandwidth - Preferred TDLS channel bandwidth when + * off-channel support is enabled. + * @Min: 0x01 + * @Max: 0x0F + * @Default: 0x07 + * + * This ini is used to configure preferred TDLS channel bandwidth when + * off-channel support is enabled. + * 0x1: 20 MHz 0x2: 40 MHz 0x4: 80 MHz 0x8: 160 MHz + * When more than one bits are set then firmware starts from the highest and + * selects one based on capability of peer. + * + * Related: gEnableTDLSSupport, gEnableTDLSOffChannel. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PREFERRED_OFF_CHANNEL_BW CFG_INI_UINT( \ + "gTDLSPrefOffChanBandwidth", \ + 1, \ + 15, \ + 7, \ + CFG_VALUE_OR_DEFAULT, \ + "Preferred TDLS channel bandwidth") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_INACTIVITY_TIME CFG_INI_UINT( \ + "gTDLSPuapsdInactivityTime", \ + 0, \ + 10, \ + 0, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Inactivity time") + +/* + * + * gTDLSPuapsdInactivityTime - Peer UAPSD Inactivity time. + * @Min: 0 + * @Max: 10 + * @Default: 0 + * + * This ini is used to configure peer uapsd inactivity time. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD CFG_INI_UINT( \ + "gTDLSPuapsdRxFrameThreshold", \ + 10, \ + 20, \ + 10, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer UAPSD Rx frame threshold") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW CFG_INI_UINT( \ + "gTDLSPuapsdPTIWindow", \ + 1, \ + 5, \ + 2, \ + CFG_VALUE_OR_DEFAULT, \ + "This ini is used to configure peer traffic indication") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT CFG_INI_UINT( \ + "gTDLSPuapsdPTRTimeout", \ + 0, \ + 10000, \ + 5000, \ + CFG_VALUE_OR_DEFAULT, \ + "Peer Traffic Response timer duration in ms") + +/* + * + * gTDLSPuapsdPTIWindow - This ini is used to configure peer traffic indication + * window. + * @Min: 1 + * @Max: 5 + * @Default: 2 + * + * This ini is used to configure buffering time in number of beacon intervals. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_EXTERNAL_CONTROL CFG_INI_BOOL( \ + "gTDLSExternalControl", \ + 1, \ + "Enable external TDLS control") + +/* + * + * gEnableTDLSWmmMode - Enables WMM support over TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to enable/disable WMM support over TDLS link. + * This is required to be set to 1 for any TDLS and uAPSD functionality. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_WMM_MODE_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSWmmMode", \ + 1, \ + "Enables WMM support over TDLS link") + +/* + * + * gEnableTDLSScan - Allow scan and maintain TDLS link. + * @Min: 0 + * @Max: 1 + * @Default: 0 + * + * This ini is used to enable/disable TDLS scan. + * 0: If peer is not buffer STA capable and device is not sleep STA + * capable, then teardown TDLS link when scan is initiated. If peer + * is buffer STA and we can be sleep STA then TDLS link is maintained + * during scan. + * 1: Maintain TDLS link and allow scan even if peer is not buffer STA + * capable and device is not sleep STA capable. There will be loss of + * Rx pkts since peer would not know when device moves away from tdls + * channel. Tx on TDLS link would stop when device moves away from tdls + * channel. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_SCAN_ENABLE CFG_INI_BOOL( \ + "gEnableTDLSScan", \ + 0, \ + "Allow scan and maintain TDLS link") + +/* + * + * gTDLSPeerKickoutThreshold - TDLS peer kick out threshold to firmware. + * @Min: 10 + * @Max: 5000 + * @Default: 96 + * + * This ini is used to configure TDLS peer kick out threshold to firmware. + * Firmware will use this value to determine, when to send TDLS + * peer kick out event to host. + * E.g. + * if peer kick out threshold is 10, then firmware will wait for 10 + * consecutive packet failures and then send TDLS kick out + * notification to host driver + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_PEER_KICKOUT_THRESHOLD CFG_INI_UINT( \ + "gTDLSPeerKickoutThreshold", \ + 10, \ + 5000, \ + 96, \ + CFG_VALUE_OR_DEFAULT, \ + "TDLS peer kick out threshold to firmware") + +/* + * + * gTDLSEnableDeferTime - Timer to defer for enabling TDLS on P2P listen. + * @Min: 500 + * @Max: 6000 + * @Default: 2000 + * + * This ini is used to set the timer to defer for enabling TDLS on P2P + * listen (value in milliseconds). + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_ENABLE_DEFER_TIMER CFG_INI_UINT( \ + "gTDLSEnableDeferTime", \ + 500, \ + 6000, \ + 2000, \ + CFG_VALUE_OR_DEFAULT, \ + "Timer to defer for enabling TDLS on P2P listen") + +/* + * + * DelayedTriggerFrmInt - delayed trigger frame interval. + * @Min: 500 + * @Max: 6000 + * @Default: 2000 + * + * This ini is used to set the delayed trigger frame interval. + * + * Related: gEnableTDLSSupport. + * + * Supported Feature: TDLS + * + * Usage: Internal/External + * + * + */ +#define CFG_TDLS_DELAYED_TRGR_FRM_INT CFG_INI_UINT( \ + "DelayedTriggerFrmInt", \ + 1, \ + 4294967295UL, \ + 3000, \ + CFG_VALUE_OR_DEFAULT, \ + "delayed trigger frame interval") + +#define CFG_TDLS_ALL \ + CFG(CFG_TDLS_QOS_WMM_UAPSD_MASK) \ + CFG(CFG_TDLS_BUF_STA_ENABLED) \ + CFG(CFG_TDLS_PUAPSD_INACT_TIME) \ + CFG(CFG_TDLS_RX_FRAME_THRESHOLD) \ + CFG(CFG_TDLS_OFF_CHANNEL_ENABLED) \ + CFG(CFG_TDLS_SUPPORT_ENABLE) \ + CFG(CFG_TDLS_IMPLICIT_TRIGGER) \ + CFG(CFG_TDLS_TX_STATS_PERIOD) \ + CFG(CFG_TDLS_TX_PACKET_THRESHOLD) \ + CFG(CFG_TDLS_MAX_DISCOVERY_ATTEMPT) \ + CFG(CFG_TDLS_IDLE_TIMEOUT) \ + CFG(CFG_TDLS_IDLE_PACKET_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_TRIGGER_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_TEARDOWN_THRESHOLD) \ + CFG(CFG_TDLS_RSSI_DELTA) \ + CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM) \ + CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_BW) \ + CFG(CFG_TDLS_PUAPSD_INACTIVITY_TIME) \ + CFG(CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD) \ + CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW) \ + CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT) \ + CFG(CFG_TDLS_EXTERNAL_CONTROL) \ + CFG(CFG_TDLS_WMM_MODE_ENABLE) \ + CFG(CFG_TDLS_SCAN_ENABLE) \ + CFG(CFG_TDLS_PEER_KICKOUT_THRESHOLD) \ + CFG(CFG_TDLS_ENABLE_DEFER_TIMER) \ + CFG(CFG_TDLS_DELAYED_TRGR_FRM_INT) + +#endif diff --git a/dispatcher/inc/wlan_tdls_cfg_api.h b/dispatcher/inc/wlan_tdls_cfg_api.h new file mode 100644 index 0000000000..6229c0ca1b --- /dev/null +++ b/dispatcher/inc/wlan_tdls_cfg_api.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2018 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: Contains p2p configures interface definitions + */ + +#ifndef _WLAN_TDLS_CFG_API_H_ +#define _WLAN_TDLS_CFG_API_H_ + +#include + +struct wlan_objmgr_psoc; + +/** + * cfg_tdls_get_support_enable() - get tdls support enable + * @psoc: pointer to psoc object + * @val: pointer to tdls support enable/disable + * + * This function gets tdls support enable + */ +QDF_STATUS +cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_support_enable() - set tdls support enable + * @psoc: pointer to psoc object + * @val: set tdls support enable/disable + * + * This function sets tdls support enable + */ +QDF_STATUS +cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_external_control() - get tdls external control + * @psoc: pointer to psoc object + * @val: pointer to tdls external control enable/disable + * + * This function gets tdls external control + */ +QDF_STATUS +cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_get_uapsd_mask() - get tdls uapsd mask + * @psoc: pointer to psoc object + * @val: pointer to tdls uapsd mask + * + * This function gets tdls uapsd mask + */ +QDF_STATUS +cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_buffer_sta_enable() - get tdls buffer sta enable + * @psoc: pointer to psoc object + * @val: pointer to tdls buffer sta enable + * + * This function gets tdls buffer sta enable + */ +QDF_STATUS +cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_buffer_sta_enable() - set tdls buffer sta enable + * @psoc: pointer to psoc object + * @val: tdls buffer sta enable + * + * This function sets tdls buffer sta enable + */ +QDF_STATUS +cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_uapsd_inactivity_time() - get tdls uapsd inactivity time + * @psoc: pointer to psoc object + * @val: pointer to tdls uapsd inactivity time + * + * This function gets tdls uapsd inactivity time + */ +QDF_STATUS +cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_rx_pkt_threshold() - get tdls rx pkt threshold + * @psoc: pointer to psoc object + * @val: pointer to tdls tdls rx pkt threshold + * + * This function gets tdls rx pkt threshold + */ +QDF_STATUS +cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *val); + +/** + * cfg_tdls_get_off_channel_enable() - get tdls off channel enable + * @psoc: pointer to psoc object + * @val: pointer to tdls off channel enable + * + * This function gets tdls off channel enable + */ +QDF_STATUS +cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_off_channel_enable() - set tdls off channel enable + * @psoc: pointer to psoc object + * @val: tdls off channel enable + * + * This function sets tdls off channel enable + */ +QDF_STATUS +cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_wmm_mode_enable() - get tdls wmm mode enable + * @psoc: pointer to psoc object + * @val: pointer to tdls wmm mode enable + * + * This function gets tdls wmm mode enable + */ +QDF_STATUS +cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_vdev_nss_2g() - set tdls vdev nss 2g + * @psoc: pointer to psoc object + * @val: tdls vdev nss 2g + * + * This function sets tdls vdev nss 2g + */ +QDF_STATUS +cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc, + uint8_t val); + +/** + * cfg_tdls_set_vdev_nss_5g() - set tdls vdev nss 5g + * @psoc: pointer to psoc object + * @val: tdls vdev nss 5g + * + * This function sets tdls vdev nss 5g + */ +QDF_STATUS +cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc, + uint8_t val); + +/** + * cfg_tdls_get_sleep_sta_enable() - get tdls sleep sta enable + * @psoc: pointer to psoc object + * @val: pointer to tdls sleep sta enable + * + * This function gets tdls sleep sta enable + */ +QDF_STATUS +cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_sleep_sta_enable() - set tdls sleep sta enable + * @psoc: pointer to psoc object + * @val: tdls sleep sta enable + * + * This function sets tdls sleep sta enable + */ +QDF_STATUS +cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +/** + * cfg_tdls_get_scan_enable() - get tdls scan enable + * @psoc: pointer to psoc object + * @val: pointer to tdls scan enable + * + * This function gets tdls scan enable + */ +QDF_STATUS +cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, + bool *val); + +/** + * cfg_tdls_set_scan_enable() - set tdls scan enable + * @psoc: pointer to psoc object + * @val: tdls scan enable + * + * This function sets tdls scan enable + */ +QDF_STATUS +cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, + bool val); + +#endif /* _WLAN_TDLS_CFG_API_H_ */ diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index eec7260b5d..c8dd05f53e 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -427,6 +427,14 @@ enum tdls_feature_bit { * @delayed_trig_framint: delayed trigger frame interval * @tdls_vdev_nss_2g: tdls NSS setting for 2G band * @tdls_vdev_nss_5g: tdls NSS setting for 5G band + * @tdls_buffer_sta_enable: tdls buffer station enable + * @tdls_off_chan_enable: tdls off channel enable + * @tdls_wmm_mode_enable: tdls wmm mode enable + * @tdls_external_control: tdls external control enable + * @tdls_implicit_trigger_enable: tdls implicit trigger enable + * @tdls_scan_enable: tdls scan enable + * @tdls_sleep_sta_enable: tdls sleep sta enable + * @tdls_support_enable: tdls support enable */ struct tdls_user_config { uint32_t tdls_tx_states_period; @@ -435,8 +443,8 @@ struct tdls_user_config { uint32_t tdls_max_discovery_attempt; uint32_t tdls_idle_timeout; uint32_t tdls_idle_pkt_threshold; - uint32_t tdls_rssi_trigger_threshold; - uint32_t tdls_rssi_teardown_threshold; + int32_t tdls_rssi_trigger_threshold; + int32_t tdls_rssi_teardown_threshold; uint32_t tdls_rssi_delta; uint32_t tdls_uapsd_mask; uint32_t tdls_uapsd_inactivity_time; @@ -449,6 +457,14 @@ struct tdls_user_config { uint32_t delayed_trig_framint; uint8_t tdls_vdev_nss_2g; uint8_t tdls_vdev_nss_5g; + bool tdls_buffer_sta_enable; + bool tdls_off_chan_enable; + bool tdls_wmm_mode_enable; + bool tdls_external_control; + bool tdls_implicit_trigger_enable; + bool tdls_scan_enable; + bool tdls_sleep_sta_enable; + bool tdls_support_enable; }; /** diff --git a/dispatcher/src/wlan_tdls_cfg.c b/dispatcher/src/wlan_tdls_cfg.c new file mode 100644 index 0000000000..b9ff892212 --- /dev/null +++ b/dispatcher/src/wlan_tdls_cfg.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2018 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 + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/** + * DOC: This file contains TDLS configures interface definitions + */ + +#include +#include "wlan_tdls_cfg_api.h" +#include "../../core/src/wlan_tdls_main.h" + +QDF_STATUS +cfg_tdls_get_support_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_support_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_support_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_support_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_external_control(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_external_control; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_uapsd_mask(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_uapsd_mask; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_buffer_sta_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_buffer_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_buffer_sta_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_uapsd_inactivity_time(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_uapsd_inactivity_time; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_rx_pkt_threshold(struct wlan_objmgr_psoc *psoc, + uint32_t *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = 0; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_rx_pkt_threshold; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_off_chan_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_off_chan_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_wmm_mode_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_vdev_nss_2g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_vdev_nss_2g = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_vdev_nss_5g(struct wlan_objmgr_psoc *psoc, + uint8_t val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_vdev_nss_5g = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_sleep_sta_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_sleep_sta_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_sleep_sta_enable = val; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_get_scan_enable(struct wlan_objmgr_psoc *psoc, + bool *val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + *val = false; + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + *val = soc_obj->tdls_configs.tdls_scan_enable; + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS +cfg_tdls_set_scan_enable(struct wlan_objmgr_psoc *psoc, + bool val) +{ + struct tdls_soc_priv_obj *soc_obj; + + soc_obj = wlan_psoc_get_tdls_soc_obj(psoc); + if (!soc_obj) { + tdls_err("tdls soc null"); + return QDF_STATUS_E_INVAL; + } + + soc_obj->tdls_configs.tdls_scan_enable = val; + + return QDF_STATUS_SUCCESS; +} diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index a477ac60ef..009d8e6ab1 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -32,6 +32,8 @@ #include #include "wlan_policy_mgr_api.h" #include "wlan_scan_ucfg_api.h" +#include "wlan_tdls_cfg.h" +#include "cfg_ucfg_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -116,11 +118,104 @@ QDF_STATUS ucfg_tdls_deinit(void) return ret; } +/** + * tdls_object_init_params() - init parameters for tdls object + * @tdls_soc_obj: pointer to tdls psoc object + * + * This function init parameters for tdls object + */ +static QDF_STATUS tdls_object_init_params( + struct tdls_soc_priv_obj *tdls_soc_obj) +{ + struct wlan_objmgr_psoc *psoc; + + if (!tdls_soc_obj) { + tdls_err("invalid param"); + return QDF_STATUS_E_INVAL; + } + + psoc = tdls_soc_obj->soc; + if (!psoc) { + tdls_err("invalid psoc object"); + return QDF_STATUS_E_INVAL; + } + + tdls_soc_obj->tdls_configs.tdls_tx_states_period = + cfg_get(psoc, CFG_TDLS_TX_STATS_PERIOD); + tdls_soc_obj->tdls_configs.tdls_tx_pkt_threshold = + cfg_get(psoc, CFG_TDLS_TX_PACKET_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rx_pkt_threshold = + cfg_get(psoc, CFG_TDLS_PUAPSD_RX_FRAME_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_max_discovery_attempt = + cfg_get(psoc, CFG_TDLS_MAX_DISCOVERY_ATTEMPT); + tdls_soc_obj->tdls_configs.tdls_idle_timeout = + cfg_get(psoc, CFG_TDLS_IDLE_TIMEOUT); + tdls_soc_obj->tdls_configs.tdls_idle_pkt_threshold = + cfg_get(psoc, CFG_TDLS_IDLE_PACKET_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_trigger_threshold = + cfg_get(psoc, CFG_TDLS_RSSI_TRIGGER_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_teardown_threshold = + cfg_get(psoc, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD); + tdls_soc_obj->tdls_configs.tdls_rssi_delta = + cfg_get(psoc, CFG_TDLS_RSSI_DELTA); + tdls_soc_obj->tdls_configs.tdls_uapsd_mask = + cfg_get(psoc, CFG_TDLS_QOS_WMM_UAPSD_MASK); + tdls_soc_obj->tdls_configs.tdls_uapsd_inactivity_time = + cfg_get(psoc, CFG_TDLS_PUAPSD_INACT_TIME); + tdls_soc_obj->tdls_configs.tdls_uapsd_pti_window = + cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW); + tdls_soc_obj->tdls_configs.tdls_uapsd_ptr_timeout = + cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT); + tdls_soc_obj->tdls_configs.tdls_pre_off_chan_num = + cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM); + tdls_soc_obj->tdls_configs.tdls_pre_off_chan_bw = + cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_BW); + tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold = + cfg_get(psoc, CFG_TDLS_PEER_KICKOUT_THRESHOLD); + tdls_soc_obj->tdls_configs.delayed_trig_framint = + cfg_get(psoc, CFG_TDLS_DELAYED_TRGR_FRM_INT); + tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable = + cfg_get(psoc, CFG_TDLS_WMM_MODE_ENABLE); + tdls_soc_obj->tdls_configs.tdls_off_chan_enable = + cfg_get(psoc, CFG_TDLS_OFF_CHANNEL_ENABLED); + tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable = + cfg_get(psoc, CFG_TDLS_BUF_STA_ENABLED); + tdls_soc_obj->tdls_configs.tdls_scan_enable = + cfg_get(psoc, CFG_TDLS_SCAN_ENABLE); + tdls_soc_obj->tdls_configs.tdls_support_enable = + cfg_get(psoc, CFG_TDLS_SUPPORT_ENABLE); + tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable = + cfg_get(psoc, CFG_TDLS_IMPLICIT_TRIGGER); + tdls_soc_obj->tdls_configs.tdls_external_control = + cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL); + + tdls_soc_obj->tdls_configs.tdls_feature_flags = + ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? + 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | + (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? + 1 << TDLS_FEATURE_WMM : 0) | + (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? + 1 << TDLS_FEATURE_BUFFER_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? + 1 << TDLS_FEATURE_SLEEP_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_scan_enable ? + 1 << TDLS_FEATURE_SCAN : 0) | + (tdls_soc_obj->tdls_configs.tdls_support_enable ? + 1 << TDLS_FEATURE_ENABLE : 0) | + (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? + 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | + (tdls_soc_obj->tdls_configs.tdls_external_control ? + 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); + + return QDF_STATUS_SUCCESS; +} + static QDF_STATUS tdls_global_init(struct tdls_soc_priv_obj *soc_obj) { uint8_t sta_idx; uint32_t feature; + tdls_object_init_params(soc_obj); soc_obj->connected_peer_count = 0; soc_obj->tdls_nss_switch_in_progress = false; soc_obj->tdls_teardown_peers_cnt = 0; @@ -228,8 +323,6 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } - /* Update TDLS user config */ - qdf_mem_copy(&soc_obj->tdls_configs, &req->config, sizeof(req->config)); tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) From d6dbd79a8ad6e52acc8e59d44e5c3eeaace70266 Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Mon, 6 Aug 2018 10:29:10 +0800 Subject: [PATCH 65/89] qcacmn: Update TDLS feature flag when hanling FW ready event It doesn't update TDLS feature flag when handling FW ready event, and cause feature mismatch between FW and host. So update TDLS feature feature flag when updating tdls configures. Change-Id: Ib5978063581cac0f4c0ebc90f8981a5b68aed1da CRs-Fixed: 2291311 --- dispatcher/src/wlan_tdls_ucfg_api.c | 47 ++++++++++++++++++----------- 1 file changed, 30 insertions(+), 17 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 009d8e6ab1..8930e02952 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -118,6 +118,34 @@ QDF_STATUS ucfg_tdls_deinit(void) return ret; } +/** + * tdls_update_feature_flag() - update tdls feature flag + * @tdls_soc_obj: pointer to tdls psoc object + * + * This function updates tdls feature flag + */ +static void +tdls_update_feature_flag(struct tdls_soc_priv_obj *tdls_soc_obj) +{ + tdls_soc_obj->tdls_configs.tdls_feature_flags = + ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? + 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | + (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? + 1 << TDLS_FEATURE_WMM : 0) | + (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? + 1 << TDLS_FEATURE_BUFFER_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? + 1 << TDLS_FEATURE_SLEEP_STA : 0) | + (tdls_soc_obj->tdls_configs.tdls_scan_enable ? + 1 << TDLS_FEATURE_SCAN : 0) | + (tdls_soc_obj->tdls_configs.tdls_support_enable ? + 1 << TDLS_FEATURE_ENABLE : 0) | + (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? + 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | + (tdls_soc_obj->tdls_configs.tdls_external_control ? + 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); +} + /** * tdls_object_init_params() - init parameters for tdls object * @tdls_soc_obj: pointer to tdls psoc object @@ -189,23 +217,7 @@ static QDF_STATUS tdls_object_init_params( tdls_soc_obj->tdls_configs.tdls_external_control = cfg_get(psoc, CFG_TDLS_EXTERNAL_CONTROL); - tdls_soc_obj->tdls_configs.tdls_feature_flags = - ((tdls_soc_obj->tdls_configs.tdls_off_chan_enable ? - 1 << TDLS_FEATURE_OFF_CHANNEL : 0) | - (tdls_soc_obj->tdls_configs.tdls_wmm_mode_enable ? - 1 << TDLS_FEATURE_WMM : 0) | - (tdls_soc_obj->tdls_configs.tdls_buffer_sta_enable ? - 1 << TDLS_FEATURE_BUFFER_STA : 0) | - (tdls_soc_obj->tdls_configs.tdls_sleep_sta_enable ? - 1 << TDLS_FEATURE_SLEEP_STA : 0) | - (tdls_soc_obj->tdls_configs.tdls_scan_enable ? - 1 << TDLS_FEATURE_SCAN : 0) | - (tdls_soc_obj->tdls_configs.tdls_support_enable ? - 1 << TDLS_FEATURE_ENABLE : 0) | - (tdls_soc_obj->tdls_configs.tdls_implicit_trigger_enable ? - 1 << TDLS_FEAUTRE_IMPLICIT_TRIGGER : 0) | - (tdls_soc_obj->tdls_configs.tdls_external_control ? - 1 << TDLS_FEATURE_EXTERNAL_CONTROL : 0)); + tdls_update_feature_flag(tdls_soc_obj); return QDF_STATUS_SUCCESS; } @@ -323,6 +335,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, return QDF_STATUS_E_FAILURE; } + tdls_update_feature_flag(soc_obj); tdls_feature_flags = soc_obj->tdls_configs.tdls_feature_flags; if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) From e173492a225045930f710b5668248b366baad75b Mon Sep 17 00:00:00 2001 From: Nirav Shah Date: Tue, 24 Jul 2018 16:33:11 +0530 Subject: [PATCH 66/89] qcacmn: umac: Add logging macros without function/line info Add per module logging macros without function/line info to avoid adding function/line info where it is not required. Change-Id: I34ba6f6485f9b506264daf4e116052d2858bed40 CRs-Fixed: 2278876 --- core/src/wlan_tdls_main.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 5c6591424b..753866ed07 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -68,6 +68,17 @@ #define tdls_alert(params...) \ QDF_TRACE_FATAL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_debug(params...) \ + QDF_TRACE_DEBUG_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_notice(params...) \ + QDF_TRACE_INFO_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_warn(params...) \ + QDF_TRACE_WARN_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_err(params...) \ + QDF_TRACE_ERROR_NO_FL(QDF_MODULE_ID_TDLS, params) +#define tdls_nofl_alert(params...) \ + QDF_TRACE_FATAL_NO_FL(QDF_MODULE_ID_TDLS, params) + #define TDLS_IS_LINK_CONNECTED(peer) \ ((TDLS_LINK_CONNECTED == (peer)->link_status) || \ (TDLS_LINK_TEARING == (peer)->link_status)) From 4568beb47c7dcab35d24214721b24cd47e0307a0 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 16 Aug 2018 15:55:25 +0530 Subject: [PATCH 67/89] qcacmn: Reduce log level for few prints to debug Reduce log level for few prints to debug to avoid flooding of prints to console. Change-Id: I514585cc87d51ead15fb1f40d45f62023628d9bb CRs-Fixed: 2296839 --- dispatcher/src/wlan_tdls_ucfg_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 8930e02952..4d0c64bcc4 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -269,7 +269,7 @@ QDF_STATUS ucfg_tdls_psoc_open(struct wlan_objmgr_psoc *psoc) QDF_STATUS status; struct tdls_soc_priv_obj *soc_obj; - tdls_notice("tdls psoc open"); + tdls_debug("tdls psoc open"); soc_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_TDLS); if (!soc_obj) { @@ -289,7 +289,7 @@ QDF_STATUS ucfg_tdls_update_config(struct wlan_objmgr_psoc *psoc, uint32_t tdls_feature_flags; struct policy_mgr_tdls_cbacks tdls_pm_call_backs; - tdls_notice("tdls update config "); + tdls_debug("tdls update config "); if (!psoc || !req) { tdls_err("psoc: 0x%pK, req: 0x%pK", psoc, req); return QDF_STATUS_E_FAILURE; From d50ff21e825d27a00023c9ea92d1fcf52a3ad719 Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 23 Aug 2018 18:25:28 +0530 Subject: [PATCH 68/89] qcacmn: Reduce log level for few prints to debug Change log level for few messages from info/warn/err to debug. Change-Id: I2fd3df21d70326301b39b91efdf827d6b391f4e3 CRs-Fixed: 2301926 --- core/src/wlan_tdls_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index bd1a2783f0..62344ed6d9 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -218,7 +218,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc_obj; uint32_t tdls_feature_flags; - tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; From e345d8539b7652423dd3e592411e3cfe0baba782 Mon Sep 17 00:00:00 2001 From: Sandeep Puligilla Date: Sat, 18 Aug 2018 12:42:41 -0700 Subject: [PATCH 69/89] qcacmn: Modify debug log levels in P2P/TDLS/SCAN Change debug message log level info/error/warn to debug. Change-Id: Ib8c5606b67ee653532489db876482b377c93e73c CRs-Fixed: 2303185 --- core/src/wlan_tdls_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 62344ed6d9..d9bb025e1d 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -153,7 +153,7 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc_obj; uint32_t tdls_feature_flags; - tdls_notice("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); + tdls_debug("tdls vdev mode %d", wlan_vdev_mlme_get_opmode(vdev)); if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE && wlan_vdev_mlme_get_opmode(vdev) != QDF_P2P_CLIENT_MODE) return QDF_STATUS_SUCCESS; @@ -203,7 +203,7 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, goto err; } - tdls_notice("tdls object attach to vdev successfully"); + tdls_debug("tdls object attach to vdev successfully"); return status; err: qdf_mem_free(tdls_vdev_obj); @@ -1343,7 +1343,7 @@ void tdls_scan_done_callback(struct tdls_soc_priv_obj *tdls_soc) return; if (TDLS_SUPPORT_DISABLED == tdls_soc->tdls_current_mode) { - tdls_notice("TDLS mode is disabled OR not enabled"); + tdls_debug("TDLS mode is disabled OR not enabled"); return; } From 5304ace8438d1c47d867acf797aa9152f32ce99d Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 30 Aug 2018 15:28:14 +0530 Subject: [PATCH 70/89] qcacmn: Configure the tdls offchannel params through IOCTL Add support to configure tdls offchannel params through IOCTL commands. Change-Id: I90ba90b5ef980f837ce4759755efe190672ad911 CRs-Fixed: 2309185 --- core/src/wlan_tdls_cmds_process.c | 80 ++++++++++++++ core/src/wlan_tdls_cmds_process.h | 34 ++++++ core/src/wlan_tdls_ct.c | 34 +----- core/src/wlan_tdls_ct.h | 38 +++++++ core/src/wlan_tdls_main.c | 9 ++ dispatcher/inc/wlan_tdls_public_structs.h | 42 +++++++- dispatcher/inc/wlan_tdls_ucfg_api.h | 29 +++++ dispatcher/src/wlan_tdls_ucfg_api.c | 122 ++++++++++++++++++++++ 8 files changed, 355 insertions(+), 33 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 8570484c2d..90805709fc 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -2334,3 +2334,83 @@ QDF_STATUS tdls_antenna_switch_flush_callback(struct scheduler_msg *msg) return QDF_STATUS_SUCCESS; } + +void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev) +{ + if (!vdev) { + tdls_err("vdev is NULL"); + return; + } + + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +} + +int tdls_process_set_offchannel(struct tdls_set_offchannel *req) +{ + int status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != + QDF_STATUS_SUCCESS) { + status = -ENOTSUPP; + goto free; + } + + tdls_debug("TDLS offchannel to be configured %d", req->offchannel); + + if (req->offchannel) + status = tdls_set_tdls_offchannel(tdls_soc_obj, + req->offchannel); + else + status = -ENOTSUPP; + +free: + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} + +int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req) +{ + int status; + + tdls_debug("TDLS offchan mode to be configured %d", req->offchan_mode); + status = tdls_set_tdls_offchannelmode(req->vdev, req->offchan_mode); + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} + +int tdls_process_set_secoffchanneloffset( + struct tdls_set_secoffchanneloffset *req) +{ + int status; + struct tdls_vdev_priv_obj *tdls_vdev_obj; + struct tdls_soc_priv_obj *tdls_soc_obj; + + if (tdls_get_vdev_objects(req->vdev, &tdls_vdev_obj, &tdls_soc_obj) != + QDF_STATUS_SUCCESS) { + status = -ENOTSUPP; + goto free; + } + + tdls_debug("TDLS offchannel offset to be configured %d", + req->offchan_offset); + status = tdls_set_tdls_secoffchanneloffset(tdls_soc_obj, + req->offchan_offset); + +free: + + if (req->callback) + req->callback(req->vdev); + qdf_mem_free(req); + + return status; +} diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index 938e966716..da14cfa6ab 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -383,4 +383,38 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req); */ void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj); +/** + * wlan_tdls_offchan_parms_callback() - Callback to release ref count + * @vdev: vdev object + * + * Return: none + */ +void wlan_tdls_offchan_parms_callback(struct wlan_objmgr_vdev *vdev); + +/** + * tdls_process_set_offchannel() - Handle set offchannel request for TDLS + * @req: TDLS set offchannel request + * + * Return: int status + */ +int tdls_process_set_offchannel(struct tdls_set_offchannel *req); + +/** + * tdls_process_set_offchan_mode() - Handle set offchan mode request for TDLS + * @req: TDLS set offchannel mode request + * + * Return: int status + */ +int tdls_process_set_offchan_mode(struct tdls_set_offchanmode *req); + +/** + * tdls_process_set_secoffchanneloffset() - Handle set sec offchannel + * offset request for TDLS + * @req: TDLS set secoffchannel offchannel request + * + * Return: int status + */ +int tdls_process_set_secoffchanneloffset( + struct tdls_set_secoffchanneloffset *req); + #endif diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index b3f28a4586..4e0b4cdbb5 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -936,16 +936,6 @@ void tdls_ct_handler(void *user_data) WLAN_TDLS_NB_ID); } -/** - * tdls_set_tdls_offchannel() - set tdls off-channel number - * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel number - * - * This function sets tdls off-channel number - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, int offchannel) { @@ -964,7 +954,7 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, } } else { tdls_err("Either TDLS or TDLS Off-channel is not enabled"); - return -ENOTSUPP; + return -ENOTSUPP; } tdls_notice("change tdls off channel from %d to %d", tdls_soc->tdls_off_channel, offchannel); @@ -972,16 +962,6 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, return 0; } -/** - * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset - * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel offset - * - * This function sets 2nd tdls off-channel offset - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, int offchanoffset) { @@ -1022,16 +1002,6 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, return 0; } -/** - * tdls_set_tdls_offchannelmode() - set tdls off-channel mode - * @adapter: Pointer to the HDD adapter - * @offchanmode: tdls off-channel mode - * - * This function sets tdls off-channel mode - * - * Return: 0 on success; negative errno otherwise - */ -static int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, int offchanmode) { @@ -1056,7 +1026,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, return -EINVAL; } - if (tdls_is_vdev_connected(vdev)) { + if (!tdls_is_vdev_connected(vdev)) { tdls_err("tdls off channel req in not associated state %d", offchanmode); return -EPERM; diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 04926b9bba..6c8dbf680f 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -206,4 +206,42 @@ void tdls_disable_offchan_and_teardown_links( QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc); +/** + * tdls_set_tdls_offchannel() - set tdls off-channel number + * @tdls_soc: tdls soc object + * @offchanmode: tdls off-channel number + * + * This function sets tdls off-channel number + * + * Return: 0 on success; negative errno otherwise + */ +int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, + int offchannel); + +/** + * tdls_set_tdls_offchannelmode() - set tdls off-channel mode + * @adapter: Pointer to the HDD adapter + * @offchannel: tdls off-channel mode + * + * This function sets tdls off-channel mode + * + * Return: 0 on success; negative errno otherwise + */ + +int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, + int offchanmode); + +/** + * tdls_set_tdls_secoffchanneloffset() - set secondary tdls off-channel offset + * @tdls_soc: tdls soc object + * @offchanoffset: tdls off-channel offset + * + * This function sets secondary tdls off-channel offset + * + * Return: 0 on success; negative errno otherwise + */ + +int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, + int offchanoffset); + #endif diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d9bb025e1d..66ebc7edb5 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -322,6 +322,15 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_GET_ALL_PEERS: tdls_get_all_peers_from_list(msg->bodyptr); break; + case TDLS_CMD_SET_OFFCHANNEL: + tdls_process_set_offchannel(msg->bodyptr); + break; + case TDLS_CMD_SET_OFFCHANMODE: + tdls_process_set_offchan_mode(msg->bodyptr); + break; + case TDLS_CMD_SET_SECOFFCHANOFFSET: + tdls_process_set_secoffchanneloffset(msg->bodyptr); + break; default: break; } diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index c8dd05f53e..3ecf2dfd26 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -190,6 +190,9 @@ enum tdls_feature_mode { * @TDLS_NOTIFY_RESET_ADAPTERS: notify adapter reset * @TDLS_CMD_GET_ALL_PEERS: get all the tdls peers from the list * @TDLS_CMD_ANTENNA_SWITCH: dynamic tdls antenna switch + * @TDLS_CMD_SET_OFFCHANNEL: tdls offchannel + * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode + * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -211,7 +214,10 @@ enum tdls_command_type { TDLS_CMD_TEARDOWN_LINKS, TDLS_NOTIFY_RESET_ADAPTERS, TDLS_CMD_GET_ALL_PEERS, - TDLS_CMD_ANTENNA_SWITCH + TDLS_CMD_ANTENNA_SWITCH, + TDLS_CMD_SET_OFFCHANNEL, + TDLS_CMD_SET_OFFCHANMODE, + TDLS_CMD_SET_SECOFFCHANOFFSET }; /** @@ -582,6 +588,9 @@ typedef QDF_STATUS /* 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); + /** * struct tdls_start_params - tdls start params * @config: tdls user config @@ -1098,4 +1107,35 @@ struct tdls_antenna_switch_request { struct wlan_objmgr_vdev *vdev; uint32_t mode; }; + +/** + * struct tdls_set_offchannel - TDLS set offchannel + * @offchannel: Updated tdls offchannel value. + */ +struct tdls_set_offchannel { + struct wlan_objmgr_vdev *vdev; + uint16_t offchannel; + tdls_offchan_parms_callback callback; +}; + +/** + * struct tdls_set_offchan_mode - TDLS set offchannel mode + * @offchan_mode: Updated tdls offchannel mode value. + */ +struct tdls_set_offchanmode { + struct wlan_objmgr_vdev *vdev; + uint8_t offchan_mode; + tdls_offchan_parms_callback callback; +}; + +/** + * struct tdls_set_offchan_offset - TDLS set offchannel mode + * @offchan_offset: Offchan offset value. + */ +struct tdls_set_secoffchanneloffset { + struct wlan_objmgr_vdev *vdev; + uint8_t offchan_offset; + tdls_offchan_parms_callback callback; +}; + #endif diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/dispatcher/inc/wlan_tdls_ucfg_api.h index 1135c48e2d..3d6570772c 100644 --- a/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -222,4 +222,33 @@ void ucfg_tdls_update_tx_pkt_cnt(struct wlan_objmgr_vdev *vdev, QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, uint32_t mode); +/** + * ucfg_set_tdls_offchannel() - Handle TDLS set offchannel + * @vdev: vdev object + * @offchannel: updated offchannel + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev, + int offchannel); + +/** + * ucfg_set_tdls_offchan_mode() - Handle TDLS set offchannel mode + * @vdev: vdev object + * @offchanmode: updated off-channel mode + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev, + int offchanmode); + +/** + * ucfg_set_tdls_secoffchanneloffset() - Handle TDLS set offchannel offset + * @vdev: vdev object + * @offchanoffset: tdls off-channel offset + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev, + int offchanoffset); #endif diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 4d0c64bcc4..5b76f0e80a 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -870,3 +870,125 @@ error: qdf_mem_free(req); return status; } + +QDF_STATUS ucfg_set_tdls_offchannel(struct wlan_objmgr_vdev *vdev, + int offchannel) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_offchannel *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchannel = offchannel; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_OFFCHANNEL; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set tdls offchannel msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} + +QDF_STATUS ucfg_set_tdls_offchan_mode(struct wlan_objmgr_vdev *vdev, + int offchanmode) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_offchanmode *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchan_mode = offchanmode; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_OFFCHANMODE; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set offchanmode msg fail"); + goto dec_ref; + } + + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} + +QDF_STATUS ucfg_set_tdls_secoffchanneloffset(struct wlan_objmgr_vdev *vdev, + int offchanoffset) +{ + int status = QDF_STATUS_SUCCESS; + struct scheduler_msg msg = {0, }; + struct tdls_set_secoffchanneloffset *req; + + req = qdf_mem_malloc(sizeof(*req)); + if (!req) { + tdls_err("mem allocate fail"); + return QDF_STATUS_E_NOMEM; + } + + status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("can't get vdev"); + goto free; + } + + req->offchan_offset = offchanoffset; + req->vdev = vdev; + req->callback = wlan_tdls_offchan_parms_callback; + msg.bodyptr = req; + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_SET_SECOFFCHANOFFSET; + status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post set secoffchan offset msg fail"); + goto dec_ref; + } + return status; + +dec_ref: + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); + +free: + qdf_mem_free(req); + return status; +} From 10a46e915bcc3973bdb9cec2e1fe1259ebd701a1 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 6 Sep 2018 14:38:13 +0530 Subject: [PATCH 71/89] qcacmn: Send TDLS set state disable command in concurrency TDLS is not supported in concurrency and FW expects set state disable command in concurrency. Currently, disable command is sent only if the active connection is present when second interface comes up. Send disable command to FW irrespecive of active TDLS connections. Change-Id: I0716a6caf76a8a69da2225f22e385ce259c231b6 CRs-Fixed: 2305714 --- core/src/wlan_tdls_ct.c | 7 +++++++ core/src/wlan_tdls_main.c | 31 ++++++------------------------- core/src/wlan_tdls_main.h | 26 ++++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 25 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 4e0b4cdbb5..6d4c1fb210 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1180,6 +1180,7 @@ void tdls_disable_offchan_and_teardown_links( struct tdls_vdev_priv_obj *tdls_vdev; struct tdls_soc_priv_obj *tdls_soc; QDF_STATUS status; + uint8_t vdev_id; status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); if (QDF_STATUS_SUCCESS != status) { @@ -1197,6 +1198,12 @@ void tdls_disable_offchan_and_teardown_links( if (!connected_tdls_peers) { tdls_notice("No TDLS connected peers to delete"); + vdev_id = vdev->vdev_objmgr.vdev_id; + if (tdls_soc->set_state_info.set_state_cnt > 0) { + tdls_debug("Disable the tdls in FW as second interface is coming up"); + tdls_send_update_to_fw(tdls_vdev, tdls_soc, true, + true, false, vdev_id); + } return; } diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 66ebc7edb5..55a810ba1f 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -717,31 +717,12 @@ void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc) tdls_process_session_update(psoc, TDLS_CMD_SESSION_DECREMENT); } -/** - * tdls_send_update_to_fw - update tdls status info - * @tdls_vdev_obj: tdls vdev private object. - * @tdls_prohibited: indicates whether tdls is prohibited. - * @tdls_chan_swit_prohibited: indicates whether tdls channel switch - * is prohibited. - * @sta_connect_event: indicate sta connect or disconnect event - * @session_id: session id - * - * Normally an AP does not influence TDLS connection between STAs - * associated to it. But AP may set bits for TDLS Prohibited or - * TDLS Channel Switch Prohibited in Extended Capability IE in - * Assoc/Re-assoc response to STA. So after STA is connected to - * an AP, call this function to update TDLS status as per those - * bits set in Ext Cap IE in received Assoc/Re-assoc response - * from AP. - * - * Return: None. - */ -static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, - struct tdls_soc_priv_obj *tdls_soc_obj, - bool tdls_prohibited, - bool tdls_chan_swit_prohibited, - bool sta_connect_event, - uint8_t session_id) +void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id) { struct tdls_info *tdls_info_to_fw; struct tdls_config_params *threshold_params; diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 753866ed07..da149aec59 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -616,6 +616,32 @@ QDF_STATUS tdls_peers_deleted_notification( */ void tdls_notify_decrement_session(struct wlan_objmgr_psoc *psoc); +/** + * tdls_send_update_to_fw - update tdls status info + * @tdls_vdev_obj: tdls vdev private object. + * @tdls_prohibited: indicates whether tdls is prohibited. + * @tdls_chan_swit_prohibited: indicates whether tdls channel switch + * is prohibited. + * @sta_connect_event: indicate sta connect or disconnect event + * @session_id: session id + * + * Normally an AP does not influence TDLS connection between STAs + * associated to it. But AP may set bits for TDLS Prohibited or + * TDLS Channel Switch Prohibited in Extended Capability IE in + * Assoc/Re-assoc response to STA. So after STA is connected to + * an AP, call this function to update TDLS status as per those + * bits set in Ext Cap IE in received Assoc/Re-assoc response + * from AP. + * + * Return: None. + */ +void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, + struct tdls_soc_priv_obj *tdls_soc_obj, + bool tdls_prohibited, + bool tdls_chan_swit_prohibited, + bool sta_connect_event, + uint8_t session_id); + /** * tdls_notify_increment_session() - Notify the session increment * @psoc: psoc object manager From 3c1a394b25c6f0189420876215aaf293ed0134ff Mon Sep 17 00:00:00 2001 From: Min Liu Date: Fri, 7 Sep 2018 16:31:20 +0800 Subject: [PATCH 72/89] qcacmn: Fix vdev ref issue in tdls_process_del_peer vdev ref is not released in some error path of tdls_process_del_peer, which will lead to vdev obj failed to be deleted. Change-Id: I439af4abbb4670d9252296b39d75eb435bb436fc CRs-Fixed: 2311161 --- core/src/wlan_tdls_cmds_process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 90805709fc..f5240e66b2 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -1141,7 +1141,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) if (!req || !req->vdev) { tdls_err("req: %pK", req); status = QDF_STATUS_E_INVAL; - goto error; + goto free_req; } vdev = req->vdev; @@ -1213,6 +1213,8 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) return status; error: status = tdls_internal_del_peer_rsp(req); + wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID); +free_req: qdf_mem_free(req); return status; } From dfa388a856a62efcabc70abf0fc34431956cc47b Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Sun, 9 Sep 2018 13:24:17 +0530 Subject: [PATCH 73/89] qcacmn: Avoid possible NULL dereference Avoid possible NULL dereference in function tdls_get_all_peers_from_list. Change-Id: I0d7dce6b8cabf5b8cee4429dbc2d5e64f1f32ce8 CRs-Fixed: 2311960 --- core/src/wlan_tdls_ct.h | 4 +- core/src/wlan_tdls_main.c | 195 ++++++++++++---------- core/src/wlan_tdls_main.h | 10 -- dispatcher/inc/wlan_tdls_public_structs.h | 6 + 4 files changed, 112 insertions(+), 103 deletions(-) diff --git a/core/src/wlan_tdls_ct.h b/core/src/wlan_tdls_ct.h index 6c8dbf680f..00e03f20d1 100644 --- a/core/src/wlan_tdls_ct.h +++ b/core/src/wlan_tdls_ct.h @@ -209,7 +209,7 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, /** * tdls_set_tdls_offchannel() - set tdls off-channel number * @tdls_soc: tdls soc object - * @offchanmode: tdls off-channel number + * @offchannel: tdls off-channel number * * This function sets tdls off-channel number * @@ -221,7 +221,7 @@ int tdls_set_tdls_offchannel(struct tdls_soc_priv_obj *tdls_soc, /** * tdls_set_tdls_offchannelmode() - set tdls off-channel mode * @adapter: Pointer to the HDD adapter - * @offchannel: tdls off-channel mode + * @offchanmode: tdls off-channel mode * * This function sets tdls off-channel mode * diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 55a810ba1f..60153249af 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -254,6 +254,110 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, return status; } +/** + * __tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: int + */ +static int __tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int i; + int len, init_len; + qdf_list_t *head; + qdf_list_node_t *p_node; + struct tdls_peer *curr_peer; + char *buf; + int buf_len; + struct tdls_vdev_priv_obj *tdls_vdev; + QDF_STATUS status; + + tdls_notice("Enter "); + + buf = get_tdls_peers->buf; + buf_len = get_tdls_peers->buf_len; + + if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { + len = qdf_scnprintf(buf, buf_len, + "\nSTA is not associated\n"); + return len; + } + + tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); + + if (!tdls_vdev) { + len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); + return len; + } + + init_len = buf_len; + len = qdf_scnprintf(buf, buf_len, + "\n%-18s%-3s%-4s%-3s%-5s\n", + "MAC", "Id", "cap", "up", "RSSI"); + buf += len; + buf_len -= len; + len = qdf_scnprintf(buf, buf_len, + "---------------------------------\n"); + buf += len; + buf_len -= len; + + for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { + head = &tdls_vdev->peer_list[i]; + status = qdf_list_peek_front(head, &p_node); + while (QDF_IS_STATUS_SUCCESS(status)) { + curr_peer = qdf_container_of(p_node, + struct tdls_peer, node); + if (buf_len < 32 + 1) + break; + len = qdf_scnprintf(buf, buf_len, + QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", + QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), + curr_peer->sta_id, + (curr_peer->tdls_support == + TDLS_CAP_SUPPORTED) ? "Y" : "N", + TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : + "N", curr_peer->rssi); + buf += len; + buf_len -= len; + status = qdf_list_peek_next(head, p_node, &p_node); + } + } + + tdls_notice("Exit "); + return init_len - buf_len; +} + +/** + * tdls_get_all_peers_from_list() - get all the tdls peers from the list + * @get_tdls_peers: get_tdls_peers object + * + * Return: None + */ +static void tdls_get_all_peers_from_list( + struct tdls_get_all_peers *get_tdls_peers) +{ + int32_t len; + struct tdls_soc_priv_obj *tdls_soc_obj; + struct tdls_osif_indication indication; + + if (!get_tdls_peers->vdev) { + qdf_mem_free(get_tdls_peers); + return; + } + len = __tdls_get_all_peers_from_list(get_tdls_peers); + + indication.status = len; + indication.vdev = get_tdls_peers->vdev; + + tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); + if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) + tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, + TDLS_EVENT_USER_CMD, &indication); + + qdf_mem_free(get_tdls_peers); +} + QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -1004,97 +1108,6 @@ static void tdls_process_reset_adapter(struct wlan_objmgr_vdev *vdev) tdls_timers_stop(tdls_vdev); } -static int __tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers) -{ - int i; - int len, init_len; - qdf_list_t *head; - qdf_list_node_t *p_node; - struct tdls_peer *curr_peer; - char *buf; - int buf_len; - struct tdls_vdev_priv_obj *tdls_vdev; - QDF_STATUS status; - - tdls_notice("Enter "); - - buf = get_tdls_peers->buf; - buf_len = get_tdls_peers->buf_len; - - if (!tdls_is_vdev_connected(get_tdls_peers->vdev)) { - len = qdf_scnprintf(buf, buf_len, - "\nSTA is not associated\n"); - return len; - } - - tdls_vdev = wlan_vdev_get_tdls_vdev_obj(get_tdls_peers->vdev); - - if (!tdls_vdev) { - len = qdf_scnprintf(buf, buf_len, "TDLS not enabled\n"); - return len; - } - - init_len = buf_len; - len = qdf_scnprintf(buf, buf_len, - "\n%-18s%-3s%-4s%-3s%-5s\n", - "MAC", "Id", "cap", "up", "RSSI"); - buf += len; - buf_len -= len; - len = qdf_scnprintf(buf, buf_len, - "---------------------------------\n"); - buf += len; - buf_len -= len; - - for (i = 0; i < WLAN_TDLS_PEER_LIST_SIZE; i++) { - head = &tdls_vdev->peer_list[i]; - status = qdf_list_peek_front(head, &p_node); - while (QDF_IS_STATUS_SUCCESS(status)) { - curr_peer = qdf_container_of(p_node, - struct tdls_peer, node); - if (buf_len < 32 + 1) - break; - len = qdf_scnprintf(buf, buf_len, - QDF_MAC_ADDR_STR "%3d%4s%3s%5d\n", - QDF_MAC_ADDR_ARRAY(curr_peer->peer_mac.bytes), - curr_peer->sta_id, - (curr_peer->tdls_support == - TDLS_CAP_SUPPORTED) ? "Y" : "N", - TDLS_IS_LINK_CONNECTED(curr_peer) ? "Y" : - "N", curr_peer->rssi); - buf += len; - buf_len -= len; - status = qdf_list_peek_next(head, p_node, &p_node); - } - } - - tdls_notice("Exit "); - return init_len - buf_len; -} - -void tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers) -{ - int32_t len; - struct tdls_soc_priv_obj *tdls_soc_obj; - struct tdls_osif_indication indication; - - if (!get_tdls_peers->vdev) - qdf_mem_free(get_tdls_peers); - - len = __tdls_get_all_peers_from_list(get_tdls_peers); - - indication.status = len; - indication.vdev = get_tdls_peers->vdev; - - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(get_tdls_peers->vdev); - if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) - tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, - TDLS_EVENT_USER_CMD, &indication); - - qdf_mem_free(get_tdls_peers); -} - void tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) { if (!vdev) { diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index da149aec59..421d6f2bd0 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -573,16 +573,6 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); - -/** - * tdls_get_all_peers_from_list() - get all the tdls peers from the list - * @get_tdls_peers: get_tdls_peers object - * - * Return: None - */ -void tdls_get_all_peers_from_list( - struct tdls_get_all_peers *get_tdls_peers); - /** * tdls_notify_reset_adapter() - notify reset adapter * @vdev: vdev object manager diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3ecf2dfd26..6ab5f663fb 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1110,7 +1110,9 @@ struct tdls_antenna_switch_request { /** * struct tdls_set_offchannel - TDLS set offchannel + * @vdev: vdev object * @offchannel: Updated tdls offchannel value. + * @callback: callback to release vdev ref. */ struct tdls_set_offchannel { struct wlan_objmgr_vdev *vdev; @@ -1120,7 +1122,9 @@ struct tdls_set_offchannel { /** * struct tdls_set_offchan_mode - TDLS set offchannel mode + * @vdev: vdev object * @offchan_mode: Updated tdls offchannel mode value. + * @callback: callback to release vdev ref. */ struct tdls_set_offchanmode { struct wlan_objmgr_vdev *vdev; @@ -1130,7 +1134,9 @@ struct tdls_set_offchanmode { /** * struct tdls_set_offchan_offset - TDLS set offchannel mode + * @vdev: vdev object * @offchan_offset: Offchan offset value. + * @callback: callback to release vdev ref. */ struct tdls_set_secoffchanneloffset { struct wlan_objmgr_vdev *vdev; From f744acaff76174829014d506dc2502cdb8f75bcf Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:34:37 +0530 Subject: [PATCH 74/89] qcacmn: Add src, and dst id support in UCFG/HDD In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I37532d323a0945b522087a23a65396ba2899fb5b CRs-Fixed: 2306011 --- dispatcher/src/wlan_tdls_ucfg_api.c | 48 +++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 5b76f0e80a..a87b42be12 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -464,7 +464,9 @@ QDF_STATUS ucfg_tdls_add_peer(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_ADD_STA; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + 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("post add peer msg fail"); qdf_mem_free(req); @@ -508,7 +510,9 @@ QDF_STATUS ucfg_tdls_update_peer(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_CHANGE_STA; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + 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("post update peer msg fail"); qdf_mem_free(req); @@ -571,7 +575,9 @@ QDF_STATUS ucfg_tdls_oper(struct wlan_objmgr_vdev *vdev, msg.bodyptr = req; msg.callback = tdls_process_cmd; msg.type = cmd; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + 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("post msg for %s fail", tdls_get_oper_str(cmd)); goto dec_ref; @@ -606,7 +612,9 @@ QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, msg.bodyptr = tdls_peers; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_GET_ALL_PEERS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (status != QDF_STATUS_SUCCESS) qdf_mem_free(tdls_peers); @@ -648,7 +656,9 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TX_ACTION; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } @@ -675,7 +685,9 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) msg.bodyptr = msg_req; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_SET_RESPONDER; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return status; } @@ -694,7 +706,9 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_CMD_TEARDOWN_LINKS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); tdls_debug("Exit "); return status; @@ -713,7 +727,9 @@ QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) msg.bodyptr = vdev; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_RESET_ADAPTERS; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return status; } @@ -738,7 +754,9 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_CONNECTION; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); return QDF_STATUS_SUCCESS; @@ -766,7 +784,9 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( msg.bodyptr = notify; msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); tdls_debug("Exit "); @@ -798,7 +818,9 @@ 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_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); tdls_debug("Exit "); @@ -856,7 +878,9 @@ QDF_STATUS ucfg_tdls_antenna_switch(struct wlan_objmgr_vdev *vdev, msg.callback = tdls_process_cmd; msg.flush_callback = tdls_antenna_switch_flush_callback; msg.type = TDLS_CMD_ANTENNA_SWITCH; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + 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("post antenna switch msg fail"); goto dec_ref; From c5d0228b58d56ee30ee26b9d2dc2fb78e05f5b5b Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Tue, 28 Aug 2018 19:50:21 +0530 Subject: [PATCH 75/89] qcacmn: Add src, and dst id support in TDLS In the scheduler_post_message, src_id is now added to know the source module of the msg. the present scheduler doesn't know about the same which is scheduler_post_msg Replace the scheduler_post_msg with scheduler_post_message Change-Id: I184827ec58625dc60be67b8f16aa7e698ecc893e CRs-Fixed: 2306014 --- core/src/wlan_tdls_cmds_process.c | 16 ++++++++++++---- core/src/wlan_tdls_ct.c | 4 +++- core/src/wlan_tdls_main.c | 12 +++++++++--- core/src/wlan_tdls_mgmt.c | 4 +++- dispatcher/src/wlan_tdls_tgt_api.c | 8 ++++++-- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index f5240e66b2..2933bae26c 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -167,7 +167,9 @@ static QDF_STATUS tdls_pe_add_peer(struct tdls_add_peer_request *req) QDF_MAC_ADDR_ARRAY(addstareq->peermac.bytes)); msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + 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("fail to post pe msg to add peer"); goto error; @@ -232,7 +234,9 @@ QDF_STATUS tdls_pe_del_peer(struct tdls_del_peer_request *req) QDF_MAC_ADDR_ARRAY(delstareq->peermac.bytes)); msg.type = soc_obj->tdls_del_sta_req; msg.bodyptr = delstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + 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("fail to post pe msg to del peer"); goto error; @@ -318,7 +322,9 @@ static QDF_STATUS tdls_pe_update_peer(struct tdls_update_peer_request *req) msg.type = soc_obj->tdls_add_sta_req; msg.bodyptr = addstareq; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + 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("fail to post pe msg to update peer"); goto error; @@ -1561,7 +1567,9 @@ tdls_wma_update_peer_state(struct tdls_soc_priv_obj *soc_obj, msg.reserved = 0; msg.bodyptr = peer_state; - status = scheduler_post_msg(QDF_MODULE_ID_WMA, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_WMA, + QDF_MODULE_ID_WMA, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("scheduler_post_msg failed"); status = QDF_STATUS_E_FAILURE; diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 6d4c1fb210..95ddd82ac9 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1165,7 +1165,9 @@ QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, msg.type = del_msg->msg_type; msg.bodyptr = del_msg; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, + QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); return status; diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 60153249af..d969d25069 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -806,7 +806,9 @@ static void tdls_process_session_update(struct wlan_objmgr_psoc *psoc, msg.callback = tdls_process_cmd; msg.type = (uint16_t)cmd_type; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) tdls_alert("message post failed "); } @@ -1142,7 +1144,9 @@ QDF_STATUS tdls_peers_deleted_notification( msg.callback = tdls_process_cmd; msg.type = TDLS_NOTIFY_STA_DISCONNECTION; - status = scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(notify); tdls_alert("message post failed "); @@ -1381,7 +1385,9 @@ 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.type = TDLS_CMD_SCAN_DONE; - scheduler_post_msg(QDF_MODULE_ID_OS_IF, &msg); + scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); return QDF_STATUS_SUCCESS; } diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 38b93d1cab..af73df1e86 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -305,7 +305,9 @@ static QDF_STATUS tdls_activate_send_mgmt_request( msg.type = tdls_soc_obj->tdls_send_mgmt_req; msg.bodyptr = tdls_mgmt_req; - status = scheduler_post_msg(QDF_MODULE_ID_PE, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); release_mgmt_ref: diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index 5c58a73361..a6eb77716f 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -205,7 +205,9 @@ tgt_tdls_event_handler(struct wlan_objmgr_psoc *psoc, msg.bodyptr = notify; msg.callback = tdls_process_evt; - status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("can't post msg to handle tdls event"); wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_SB_ID); @@ -283,7 +285,9 @@ 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; - status = scheduler_post_msg(QDF_MODULE_ID_TARGET_IF, &msg); + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); qdf_nbuf_free(buf); From 6fdaf77b6d7c247f317522c7ea1975a44082ba67 Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Thu, 30 Aug 2018 13:23:30 +0800 Subject: [PATCH 76/89] qcacmn: MCL part change after serialization enhancement 1. Keep serialization legacy api not broken. Serialization enhancement have much changes on internal struct and API, need re-implement serialization legacy APIs. 2. Set all cmds on MCL platform as blocking type. MCL dones't support cmd concurrency on multi vdevs, while WIN need it. Change-Id: I5d5d6e0e16becb0b0f285fd8ed20982f2819659c CRs-Fixed: 2315407 --- core/src/wlan_tdls_cmds_process.c | 3 +++ core/src/wlan_tdls_mgmt.c | 1 + 2 files changed, 4 insertions(+) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 2933bae26c..ded673c0b5 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -825,6 +825,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; cmd.vdev = vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, @@ -1034,6 +1035,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; cmd.vdev = req->vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, @@ -1187,6 +1189,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.is_high_priority = false; cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; cmd.vdev = vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("req: 0x%pK wlan_serialization_request status:%d", req, diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index af73df1e86..e60d2824c6 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -403,6 +403,7 @@ QDF_STATUS tdls_process_mgmt_req( cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = tdls_mgmt_req->vdev; + cmd.is_blocking = true; ser_cmd_status = wlan_serialization_request(&cmd); tdls_debug("wlan_serialization_request status:%d", ser_cmd_status); From a105eeecdb8ec4df96710c28a59ec78089c22e9c Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Wed, 3 Oct 2018 10:51:38 +0530 Subject: [PATCH 77/89] qcacmn: Update TDLS opclass correctly to FW Due to change in Opclass calculation in the new regulatory component invalid opclass is returned for the TDLS component. Update arguments to calculate opclass correctly to regulatory component. Change-Id: I062bbb55d283f9525da241d32177e26d07aa8590 CRs-Fixed: 2325834 --- core/src/wlan_tdls_ct.c | 10 ++++++---- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 95ddd82ac9..d7c50ab7c6 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -979,17 +979,19 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, switch (offchanoffset) { case TDLS_SEC_OFFCHAN_OFFSET_0: - tdls_soc->tdls_channel_offset = (1 << BW_20_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW20; break; case TDLS_SEC_OFFCHAN_OFFSET_40PLUS: + tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; + break; case TDLS_SEC_OFFCHAN_OFFSET_40MINUS: - tdls_soc->tdls_channel_offset = (1 << BW_40_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY; break; case TDLS_SEC_OFFCHAN_OFFSET_80: - tdls_soc->tdls_channel_offset = (1 << BW_80_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BW80; break; case TDLS_SEC_OFFCHAN_OFFSET_160: - tdls_soc->tdls_channel_offset = (1 << BW_160_OFFSET_BIT); + tdls_soc->tdls_channel_offset = BWALL; break; default: tdls_err("Invalid tdls secondary off channel offset %d", diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 6ab5f663fb..3aa85b71ae 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -1140,7 +1140,7 @@ struct tdls_set_offchanmode { */ struct tdls_set_secoffchanneloffset { struct wlan_objmgr_vdev *vdev; - uint8_t offchan_offset; + int offchan_offset; tdls_offchan_parms_callback callback; }; From fd4e3d3ee3ada8287d8fafd9a169b60db00b732e Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 15 Oct 2018 14:31:36 +0530 Subject: [PATCH 78/89] qcacmn: Remove TDLS mgmt tx command from active list If bss peer is freed after posting TDLS mgmt request command to serialization component. Free the tdls mgmt req command from active list. Change-Id: I6bf2c3518dfc64052470375e4018e56abdcfcabb CRs-Fixed: 2333288 --- core/src/wlan_tdls_cmds_process.c | 2 +- core/src/wlan_tdls_cmds_process.h | 13 +++++++++++++ core/src/wlan_tdls_mgmt.c | 10 +++++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index ded673c0b5..8c9f985a5e 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -97,7 +97,7 @@ static char *tdls_get_ser_cmd_str(enum wlan_serialization_cmd_type type) } } -static void +void tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, enum wlan_serialization_cmd_type type) { diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index da14cfa6ab..bebf1b099f 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -291,6 +291,19 @@ QDF_STATUS tdls_process_add_peer_rsp(struct tdls_add_sta_rsp *rsp); void tdls_reset_nss(struct tdls_soc_priv_obj *tdls_soc, uint8_t action_code); +/** + * tdls_release_serialization_command() - TDLS wrapper to + * relases serialization command. + * @vdev: Object manager vdev + * @type: command to release. + * + * Return: None + */ + +void +tdls_release_serialization_command(struct wlan_objmgr_vdev *vdev, + enum wlan_serialization_cmd_type type); + /** * tdls_set_cap() - set TDLS capability type * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index e60d2824c6..8b051ac368 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -206,7 +206,6 @@ tdls_internal_send_mgmt_tx_done(struct tdls_action_frame_request *req, indication.status = status; indication.vdev = req->vdev; - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(req->vdev); if (tdls_soc_obj && tdls_soc_obj->tdls_event_cb) tdls_soc_obj->tdls_event_cb(tdls_soc_obj->tdls_evt_cb_data, @@ -272,8 +271,8 @@ static QDF_STATUS tdls_activate_send_mgmt_request( peer = wlan_vdev_get_bsspeer(action_req->vdev); - if (QDF_STATUS_SUCCESS != wlan_objmgr_peer_try_get_ref(peer, - WLAN_TDLS_SB_ID)) { + status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); + if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(tdls_mgmt_req); goto release_mgmt_ref; } @@ -315,6 +314,11 @@ release_mgmt_ref: /*update tdls nss infornation based on action code */ tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_internal_send_mgmt_tx_done(action_req, status); + tdls_release_serialization_command(action_req->vdev, + WLAN_SER_CMD_TDLS_SEND_MGMT); + } return status; } From a82fdd95678983190e16f95a25ba3222b53d48c0 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Thu, 11 Oct 2018 14:34:37 +0530 Subject: [PATCH 79/89] qcacmn: Delete all peers in TDLS component In case of heartbeat failure or deauth from AP, From lim Del sta requests are sent to FW and with response required false, Since del sta response is not received TDLS component is not notified to reset the local tdls component structures and also upper layers are notified of this peer deletion. Change-Id: Ica0b150df7646af60868b2806432795896c75bcd CRs-Fixed: 2324559 --- core/src/wlan_tdls_main.c | 134 ++++++++++++++++++++++ core/src/wlan_tdls_main.h | 11 ++ dispatcher/inc/wlan_tdls_public_structs.h | 19 ++- dispatcher/inc/wlan_tdls_tgt_api.h | 14 ++- dispatcher/src/wlan_tdls_tgt_api.c | 47 ++++++++ 5 files changed, 223 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index d969d25069..312a74bf6e 100644 --- a/core/src/wlan_tdls_main.c +++ b/core/src/wlan_tdls_main.c @@ -358,6 +358,106 @@ static void tdls_get_all_peers_from_list( qdf_mem_free(get_tdls_peers); } +/** + * tdls_process_reset_all_peers() - Reset all tdls peers + * @delete_all_peers_ind: Delete all peers indication + * + * This function is called to reset all tdls peers and + * notify upper layers of teardown inidcation + * + * Return: QDF_STATUS + */ + +static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + uint8_t staidx; + struct tdls_peer *curr_peer = NULL; + struct tdls_vdev_priv_obj *tdls_vdev; + struct tdls_soc_priv_obj *tdls_soc; + uint8_t reset_session_id; + + status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); + if (QDF_STATUS_SUCCESS != status) { + tdls_err("tdls objects are NULL "); + return status; + } + + if (!tdls_soc->connected_peer_count) { + tdls_debug("No tdls connected peers"); + return status; + } + + reset_session_id = tdls_vdev->session_id; + for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; + staidx++) { + if (tdls_soc->tdls_conn_info[staidx].sta_id + == INVALID_TDLS_PEER_ID) + continue; + if (tdls_soc->tdls_conn_info[staidx].session_id != + reset_session_id) + continue; + + curr_peer = + tdls_find_all_peer(tdls_soc, + tdls_soc->tdls_conn_info[staidx]. + peer_mac.bytes); + if (!curr_peer) + continue; + + tdls_notice("indicate TDLS teardown (staId %d)", + curr_peer->sta_id); + + /* Indicate teardown to supplicant */ + tdls_indicate_teardown(tdls_vdev, + curr_peer, + TDLS_TEARDOWN_PEER_UNSPEC_REASON); + + tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes); + + if (tdls_soc->tdls_dereg_peer) + tdls_soc->tdls_dereg_peer( + tdls_soc->tdls_peer_context, + wlan_vdev_get_id(vdev), + curr_peer->sta_id); + 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; + + qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac, + sizeof(struct qdf_mac_addr)); + } + return status; +} + +/** + * tdls_reset_all_peers() - Reset all tdls peers + * @delete_all_peers_ind: Delete all peers indication + * + * This function is called to reset all tdls peers and + * notify upper layers of teardown inidcation + * + * Return: QDF_STATUS + */ +static QDF_STATUS tdls_reset_all_peers( + struct tdls_delete_all_peers_params *delete_all_peers_ind) +{ + QDF_STATUS status; + + if (!delete_all_peers_ind || !delete_all_peers_ind->vdev) { + tdls_err("invalid param"); + return QDF_STATUS_E_INVAL; + } + + 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); + + qdf_mem_free(delete_all_peers_ind); + return status; +} + QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -435,6 +535,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SET_SECOFFCHANOFFSET: tdls_process_set_secoffchanneloffset(msg->bodyptr); break; + case TDLS_DELETE_ALL_PEERS_INDICATION: + tdls_reset_all_peers(msg->bodyptr); + break; default: break; } @@ -1156,6 +1259,37 @@ QDF_STATUS tdls_peers_deleted_notification( return QDF_STATUS_SUCCESS; } +QDF_STATUS tdls_delete_all_peers_indication( + struct tdls_delete_all_peers_params *delete_peers_ind) +{ + struct scheduler_msg msg = {0, }; + struct tdls_delete_all_peers_params *indication; + QDF_STATUS status; + + indication = qdf_mem_malloc(sizeof(*indication)); + if (!indication) { + tdls_err("memory allocation failed !!!"); + return QDF_STATUS_E_NULL_VALUE; + } + + *indication = *delete_peers_ind; + + msg.bodyptr = indication; + msg.callback = tdls_process_cmd; + msg.type = TDLS_DELETE_ALL_PEERS_INDICATION; + + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(indication); + tdls_alert("message post failed "); + return QDF_STATUS_E_FAILURE; + } + + return QDF_STATUS_SUCCESS; +} + /** * tdls_set_mode_in_vdev() - set TDLS mode * @tdls_vdev: tdls vdev object diff --git a/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index 421d6f2bd0..fc12304291 100644 --- a/core/src/wlan_tdls_main.h +++ b/core/src/wlan_tdls_main.h @@ -725,4 +725,15 @@ void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev, QDF_STATUS tdls_set_offchan_mode(struct wlan_objmgr_psoc *psoc, struct tdls_channel_switch_params *param); +/** + * tdls_delete_all_peers_indication() - update tdls status info + * @delete_peers_ind: Delete peers indication params + * + * 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); #endif diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3aa85b71ae..261a1e9af8 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -193,6 +193,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SET_OFFCHANNEL: tdls offchannel * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset + * @TDLS_DELETE_ALL_PEERS_INDICATION: tdls delete all peers indication */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -217,7 +218,8 @@ enum tdls_command_type { TDLS_CMD_ANTENNA_SWITCH, TDLS_CMD_SET_OFFCHANNEL, TDLS_CMD_SET_OFFCHANMODE, - TDLS_CMD_SET_SECOFFCHANOFFSET + TDLS_CMD_SET_SECOFFCHANOFFSET, + TDLS_DELETE_ALL_PEERS_INDICATION }; /** @@ -591,6 +593,11 @@ 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 @@ -1072,6 +1079,16 @@ struct tdls_sta_notify_params { 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; +}; + /** * struct tdls_set_mode_params - TDLS set mode params * @vdev: vdev object diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/dispatcher/inc/wlan_tdls_tgt_api.h index 4b1e99c4a3..14a19006b9 100644 --- a/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/dispatcher/inc/wlan_tdls_tgt_api.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2018 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 @@ -158,4 +158,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, uint32_t session_id); +/** + * tgt_tdls_delete_all_peers_indication()- Indication to tdls component + * @psoc: soc object + * @session_id: session id + * + * This function called from legacy lim to tdls component to delete tdls peers. + * + * Return: None + */ +void tgt_tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc, + uint32_t session_id); + #endif diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index a6eb77716f..cf43a2f64b 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/dispatcher/src/wlan_tdls_tgt_api.c @@ -375,3 +375,50 @@ void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, } } +/** + * 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); +} + +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); + } +} + From 3515e05ceeb275c637f0708953f03ab5899bf683 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 23 Oct 2018 17:55:18 +0530 Subject: [PATCH 80/89] qcacmn: Take vdev ref before posting the tdls mgmt tx command Before posting the TDLS_CMD_TX_ACTION to scheduler thread take the vdev ref with module id TDLS and release the ref as part of freeing this command. Change-Id: Id05962a1c9fc415199f347c5d85d1e0670dc247c CRs-Fixed: 2338113 --- core/src/wlan_tdls_mgmt.c | 32 ++++++++++----------- dispatcher/src/wlan_tdls_ucfg_api.c | 43 ++++++++++++++++++++++++++--- 2 files changed, 53 insertions(+), 22 deletions(-) diff --git a/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 8b051ac368..0b4000e3fc 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/core/src/wlan_tdls_mgmt.c @@ -225,15 +225,10 @@ static QDF_STATUS tdls_activate_send_mgmt_request( if (!action_req || !action_req->vdev) return QDF_STATUS_E_NULL_VALUE; - if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(action_req->vdev, - WLAN_TDLS_SB_ID)) - return QDF_STATUS_E_NULL_VALUE; - - tdls_soc_obj = wlan_vdev_get_tdls_soc_obj(action_req->vdev); if (!tdls_soc_obj) { status = QDF_STATUS_E_NULL_VALUE; - goto release_mgmt_ref; + goto release_cmd; } tdls_mgmt_req = qdf_mem_malloc(sizeof(struct tdls_send_mgmt_request) + @@ -242,7 +237,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( status = QDF_STATUS_E_NOMEM; tdls_err("mem alloc failed "); QDF_ASSERT(0); - goto release_mgmt_ref; + goto release_cmd; } tdls_debug("session_id %d " @@ -274,7 +269,7 @@ static QDF_STATUS tdls_activate_send_mgmt_request( status = wlan_objmgr_peer_try_get_ref(peer, WLAN_TDLS_SB_ID); if (QDF_IS_STATUS_ERROR(status)) { qdf_mem_free(tdls_mgmt_req); - goto release_mgmt_ref; + goto release_cmd; } qdf_mem_copy(tdls_mgmt_req->bssid.bytes, @@ -309,9 +304,8 @@ static QDF_STATUS tdls_activate_send_mgmt_request( QDF_MODULE_ID_PE, &msg); wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID); -release_mgmt_ref: - wlan_objmgr_vdev_release_ref(action_req->vdev, WLAN_TDLS_SB_ID); +release_cmd: /*update tdls nss infornation based on action code */ tdls_reset_nss(tdls_soc_obj, action_req->chk_frame->action_code); if (QDF_IS_STATUS_ERROR(status)) { @@ -352,13 +346,13 @@ tdls_send_mgmt_serialize_callback(struct wlan_serialization_command *cmd, */ status = tdls_internal_send_mgmt_tx_done(req, QDF_STATUS_E_FAILURE); - qdf_mem_free(req); break; case WLAN_SER_CB_RELEASE_MEM_CMD: /* command successfully completed. * release tdls_action_frame_request memory */ + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); qdf_mem_free(req); break; @@ -384,8 +378,7 @@ QDF_STATUS tdls_process_mgmt_req( if (status != QDF_STATUS_SUCCESS) { status = tdls_internal_send_mgmt_tx_done(tdls_mgmt_req, status); - qdf_mem_free(tdls_mgmt_req); - return status; + goto error_mgmt; } /* update the responder, status code information @@ -422,14 +415,17 @@ QDF_STATUS tdls_process_mgmt_req( case WLAN_SER_CMD_DENIED_LIST_FULL: case WLAN_SER_CMD_DENIED_RULES_FAILED: case WLAN_SER_CMD_DENIED_UNSPECIFIED: - /* free the request */ - qdf_mem_free(tdls_mgmt_req); - break; - + status = QDF_STATUS_E_FAILURE; + goto error_mgmt; default: QDF_ASSERT(0); status = QDF_STATUS_E_INVAL; - break; + goto error_mgmt; } return status; + +error_mgmt: + wlan_objmgr_vdev_release_ref(tdls_mgmt_req->vdev, WLAN_TDLS_NB_ID); + qdf_mem_free(tdls_mgmt_req); + return status; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index a87b42be12..62e5a73c24 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -622,11 +622,28 @@ QDF_STATUS ucfg_tdls_get_all_peers(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_SUCCESS; } +static QDF_STATUS tdls_send_mgmt_frame_flush_callback(struct scheduler_msg *msg) +{ + struct tdls_action_frame_request *req; + + if (!msg || !msg->bodyptr) { + tdls_err("msg or msg->bodyptr is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + req = msg->bodyptr; + if (req->vdev) + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); + + qdf_mem_free(req); + return QDF_STATUS_SUCCESS; +} + QDF_STATUS ucfg_tdls_send_mgmt_frame( struct tdls_action_frame_request *req) { struct scheduler_msg msg = {0, }; struct tdls_action_frame_request *mgmt_req; + QDF_STATUS status; if (!req || !req->vdev) { tdls_err("Invalid mgmt req params %pK", req); @@ -653,14 +670,32 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( tdls_debug("vdev id: %d, session id : %d", mgmt_req->vdev_id, mgmt_req->session_id); + status = wlan_objmgr_vdev_try_get_ref(req->vdev, WLAN_TDLS_NB_ID); + + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("Unable to get vdev reference for tdls module"); + goto mem_free; + } + msg.bodyptr = mgmt_req; msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_send_mgmt_frame_flush_callback; msg.type = TDLS_CMD_TX_ACTION; - scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); + 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 the mgmt tx cmd to scheduler thread"); + goto release_ref; + } - return QDF_STATUS_SUCCESS; + return status; + +release_ref: + wlan_objmgr_vdev_release_ref(req->vdev, WLAN_TDLS_NB_ID); +mem_free: + qdf_mem_free(mgmt_req); + return status; } QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) From 223e95934e842e2a82d234ce4ba25ba3ae51a84c Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 29 Oct 2018 14:47:43 +0530 Subject: [PATCH 81/89] qcacmn: Delete connection in progress tdls peers TDLS peer has to be deleted before sending the TDLS disable command to FW, otherwise FW may assert due to the invalid sequence of peer delete and TDLS set state command. So Delete TDLS peers for those the connection is in progress along with the active TDLS peers before disabling the TDLS. Change-Id: Ic52c44dea947095cfe5e4dfe36eec271b1f46867 CRs-Fixed: 2340759 --- core/src/wlan_tdls_ct.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d7c50ab7c6..e81c2e5b42 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1185,6 +1185,7 @@ void tdls_disable_offchan_and_teardown_links( struct tdls_soc_priv_obj *tdls_soc; QDF_STATUS status; uint8_t vdev_id; + bool tdls_in_progress = false; status = tdls_get_vdev_objects(vdev, &tdls_vdev, &tdls_soc); if (QDF_STATUS_SUCCESS != status) { @@ -1199,9 +1200,11 @@ void tdls_disable_offchan_and_teardown_links( } connected_tdls_peers = tdls_soc->connected_peer_count; + if (tdls_is_progress(tdls_vdev, NULL, 0)) + tdls_in_progress = true; - if (!connected_tdls_peers) { - tdls_notice("No TDLS connected peers to delete"); + if (!(connected_tdls_peers || tdls_in_progress)) { + tdls_notice("No TDLS connected/progress peers to delete"); vdev_id = vdev->vdev_objmgr.vdev_id; if (tdls_soc->set_state_info.set_state_cnt > 0) { tdls_debug("Disable the tdls in FW as second interface is coming up"); From af02af5f9e983a363dd8636f0078a0d71fecebb1 Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Wed, 24 Oct 2018 15:08:00 +0800 Subject: [PATCH 82/89] qcacmn: Fix potential resource leak when post msg in TDLS Fix potentail memory leak when post message in TDLS module: 1. Add flush callback to hanlde memory free and release reference count; 2. Check the return status when post message and free the resource for failure case. Change-Id: I0a693ccb5704509a4220f26e024ce8c6c823890c CRs-Fixed: 2341652 --- core/src/wlan_tdls_ct.c | 14 +++ core/src/wlan_tdls_main.c | 105 ++++++++++++++----- core/src/wlan_tdls_main.h | 16 +-- core/src/wlan_tdls_mgmt.c | 18 ++++ dispatcher/inc/wlan_tdls_public_structs.h | 11 -- dispatcher/src/wlan_tdls_tgt_api.c | 119 +++++++--------------- dispatcher/src/wlan_tdls_ucfg_api.c | 99 +++++++++++++++--- 7 files changed, 246 insertions(+), 136 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index e81c2e5b42..7be612d4b0 100644 --- a/core/src/wlan_tdls_ct.c +++ b/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/core/src/wlan_tdls_main.c b/core/src/wlan_tdls_main.c index 312a74bf6e..7295adda96 100644 --- a/core/src/wlan_tdls_main.c +++ b/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/core/src/wlan_tdls_main.h b/core/src/wlan_tdls_main.h index fc12304291..c03eb16abf 100644 --- a/core/src/wlan_tdls_main.h +++ b/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/core/src/wlan_tdls_mgmt.c b/core/src/wlan_tdls_mgmt.c index 0b4000e3fc..47b30c4f9b 100644 --- a/core/src/wlan_tdls_mgmt.c +++ b/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/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 261a1e9af8..9fbb273eef 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/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/dispatcher/src/wlan_tdls_tgt_api.c b/dispatcher/src/wlan_tdls_tgt_api.c index cf43a2f64b..bb09a0e8b4 100644 --- a/dispatcher/src/wlan_tdls_tgt_api.c +++ b/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/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index 62e5a73c24..e1936cfc62 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/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 "); From 4cfc4d37d5b525cc9538321ac8c27e01f0d68d96 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 30 Oct 2018 15:18:14 +0530 Subject: [PATCH 83/89] qcacmn: Pass valid arguments to hdd_wmm_is_acm_allowed Currently pointer of the vdev object is sent to the callback hdd_wmm_is_acm_allowed to get the adapter. But this can't be used to get the adapter. Instead pass the vdev id to get the adapter. Change-Id: I3cb2f58d09a263c77a3696a36e863cc4137c7821 CRs-Fixed: 2341799 --- core/src/wlan_tdls_cmds_process.c | 4 +++- dispatcher/inc/wlan_tdls_public_structs.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 8c9f985a5e..00c384ed41 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -664,6 +664,7 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) struct tdls_peer *curr_peer; struct tdls_peer *temp_peer; QDF_STATUS status; + uint8_t vdev_id; struct tdls_validate_action_req *tdls_validate = tdls_mgmt_req->chk_frame; @@ -723,7 +724,8 @@ int tdls_validate_mgmt_request(struct tdls_action_frame_request *tdls_mgmt_req) } /* call hdd_wmm_is_acm_allowed() */ - if (!tdls_soc->tdls_wmm_cb(&tdls_vdev->vdev)) { + vdev_id = wlan_vdev_get_id(tdls_validate->vdev); + if (!tdls_soc->tdls_wmm_cb(vdev_id)) { tdls_debug("admission ctrl set to VI, send the frame with least AC (BK) for action %d", tdls_validate->action_code); tdls_mgmt_req->use_default_ac = false; diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 9fbb273eef..3e05b007b6 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -553,7 +553,7 @@ typedef void (*tdls_rx_callback)(void *user_data, * * Return: true or false */ -typedef bool (*tdls_wmm_check)(struct wlan_objmgr_vdev **vdev); +typedef bool (*tdls_wmm_check)(uint8_t vdev_id); /* This callback is used to report state change of peer to wpa_supplicant */ From ce77466cdb32050c0824e2155047d7f4502743e5 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Fri, 2 Nov 2018 15:17:53 +0530 Subject: [PATCH 84/89] qcacmn: Send the supported channel list length correctly to FW Currently, peer supported channel list length is updated first, and then channel list updated by removing the DFS and invalid channels. So, Wrong channel list length is sent to FW. Change-Id: I1e71bdeae3d5368fbea85ae5e47e13c326e36375 CRs-Fixed: 2344729 --- core/src/wlan_tdls_peer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/wlan_tdls_peer.c b/core/src/wlan_tdls_peer.c index 3f8a132e0e..ff4bf86379 100644 --- a/core/src/wlan_tdls_peer.c +++ b/core/src/wlan_tdls_peer.c @@ -493,7 +493,6 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer->off_channel_capable; peer_param->peer_cap.peer_curr_operclass = 0; peer_param->peer_cap.self_curr_operclass = 0; - peer_param->peer_cap.peer_chanlen = peer->supported_channels_len; peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num; peer_param->peer_cap.pref_off_chan_bandwidth = soc_obj->tdls_configs.tdls_pre_off_chan_bw; @@ -520,6 +519,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param, peer_param->peer_cap.peer_chan[num].pwr = wlan_reg_get_channel_reg_power(pdev, chan_id); peer_param->peer_cap.peer_chan[num].dfs_set = false; + peer_param->peer_cap.peer_chanlen++; num++; } } From e9abcb6c8388c0b8efa4d3910843bdcd3565ffab Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Mon, 5 Nov 2018 17:56:53 +0530 Subject: [PATCH 85/89] qcacmn: Increase serialization command timeout Increase the serialization command timeout for add sta and del sta of tdls peers requests. Change-Id: If6ba6aa1297afaea1fd86bf406dcbb6e4e461d25 CRs-Fixed: 2345425 --- core/src/wlan_tdls_cmds_process.c | 6 +++--- core/src/wlan_tdls_mgmt.h | 5 +---- dispatcher/inc/wlan_tdls_public_structs.h | 7 +++++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.c b/core/src/wlan_tdls_cmds_process.c index 00c384ed41..a27c040ef6 100644 --- a/core/src/wlan_tdls_cmds_process.c +++ b/core/src/wlan_tdls_cmds_process.c @@ -825,7 +825,7 @@ QDF_STATUS tdls_process_add_peer(struct tdls_add_peer_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = vdev; cmd.is_blocking = true; @@ -1035,7 +1035,7 @@ QDF_STATUS tdls_process_update_peer(struct tdls_update_peer_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_ADD_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = req->vdev; cmd.is_blocking = true; @@ -1189,7 +1189,7 @@ QDF_STATUS tdls_process_del_peer(struct tdls_oper_request *req) cmd.umac_cmd = req; cmd.source = WLAN_UMAC_COMP_TDLS; cmd.is_high_priority = false; - cmd.cmd_timeout_duration = WAIT_TIME_TDLS_DEL_STA; + cmd.cmd_timeout_duration = TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT; cmd.vdev = vdev; cmd.is_blocking = true; diff --git a/core/src/wlan_tdls_mgmt.h b/core/src/wlan_tdls_mgmt.h index a6973f17d7..ce6f930798 100644 --- a/core/src/wlan_tdls_mgmt.h +++ b/core/src/wlan_tdls_mgmt.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018 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 @@ -25,9 +25,6 @@ #ifndef _WLAN_TDLS_MGMT_H_ #define _WLAN_TDLS_MGMT_H_ -/* default tdls serialize timeout is set to 10 secs */ -#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 - #define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24 #define TDLS_PUBLIC_ACTION_FRAME 4 #define TDLS_PUBLIC_ACTION_DISC_RESP 14 diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index 3e05b007b6..dd8f1b9237 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -50,11 +50,14 @@ #define AC_PRIORITY_NUM 4 +/* default tdls serialize timeout is set to 10 secs */ +#define TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT 10000 + /** Maximum time(ms) to wait for tdls add sta to complete **/ -#define WAIT_TIME_TDLS_ADD_STA 1500 +#define WAIT_TIME_TDLS_ADD_STA (TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT + 1000) /** Maximum time(ms) to wait for tdls del sta to complete **/ -#define WAIT_TIME_TDLS_DEL_STA 1500 +#define WAIT_TIME_TDLS_DEL_STA (TDLS_DEFAULT_SERIALIZE_CMD_TIMEOUT + 1000) /** Maximum time(ms) to wait for Link Establish Req to complete **/ #define WAIT_TIME_TDLS_LINK_ESTABLISH_REQ 1500 From 87107dd933953ac4d3a4f4c9821a325af2830b95 Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 13 Nov 2018 13:10:56 +0530 Subject: [PATCH 86/89] qcacmn: Avoid redefination of tdls_add_oper enum Enums tdls_add_oper and TdlsAddOper are same. Instead redefining use the same enum across different files. Change-Id: Ibb71b0f80e156e4bd3a345a56c7b4d99ce770ef7 CRs-Fixed: 2349643 --- core/src/wlan_tdls_cmds_process.h | 13 ------------- dispatcher/inc/wlan_tdls_public_structs.h | 13 +++++++++++++ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/core/src/wlan_tdls_cmds_process.h b/core/src/wlan_tdls_cmds_process.h index bebf1b099f..e66b41aa69 100644 --- a/core/src/wlan_tdls_cmds_process.h +++ b/core/src/wlan_tdls_cmds_process.h @@ -29,19 +29,6 @@ ((TDLS_SETUP_REQUEST <= action) && \ (TDLS_SETUP_CONFIRM >= action)) - -/** - * enum tdls_add_oper - add peer type - * @TDLS_OPER_NONE: none - * @TDLS_OPER_ADD: add new peer - * @TDLS_OPER_UPDATE: used to update peer - */ -enum tdls_add_oper { - TDLS_OPER_NONE, - TDLS_OPER_ADD, - TDLS_OPER_UPDATE -}; - /** * enum legacy_result_code - defined to comply with tSirResultCodes, need refine * when mlme converged. diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/dispatcher/inc/wlan_tdls_public_structs.h index dd8f1b9237..07bc155d95 100644 --- a/dispatcher/inc/wlan_tdls_public_structs.h +++ b/dispatcher/inc/wlan_tdls_public_structs.h @@ -80,6 +80,19 @@ #define INVALID_TDLS_PEER_ID 0xFF #define TDLS_STA_INDEX_CHECK(sta_id) \ (((sta_id) >= 0) && ((sta_id) < 0xFF)) + +/** + * enum tdls_add_oper - add peer type + * @TDLS_OPER_NONE: none + * @TDLS_OPER_ADD: add new peer + * @TDLS_OPER_UPDATE: used to update peer + */ +enum tdls_add_oper { + TDLS_OPER_NONE, + TDLS_OPER_ADD, + TDLS_OPER_UPDATE +}; + /** * enum tdls_conc_cap - tdls concurrency support * @TDLS_SUPPORTED_ONLY_ON_STA: only support sta tdls From 07c45b33e8533e006b8cf71eab64782e861957eb Mon Sep 17 00:00:00 2001 From: Frank Liu Date: Fri, 16 Nov 2018 11:41:20 +0800 Subject: [PATCH 87/89] qcacmn: Fix KW issue in tdls Potential NULL pointer dereferences in below functions: tdls_delete_all_tdls_peers_flush_cb() ucfg_tdls_notify_sta_connect() Change-Id: Iee31d91b31c5921fbd5cc70e0b893093b496ee43 CRs-Fixed: 2350930 --- core/src/wlan_tdls_ct.c | 6 +++--- dispatcher/src/wlan_tdls_ucfg_api.c | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index 7be612d4b0..d2fa6bb71a 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -1123,10 +1123,10 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, static QDF_STATUS tdls_delete_all_tdls_peers_flush_cb(struct scheduler_msg *msg) { - if (msg && msg->bodyptr) + if (msg && msg->bodyptr) { qdf_mem_free(msg->bodyptr); - - msg->bodyptr = NULL; + msg->bodyptr = NULL; + } return QDF_STATUS_SUCCESS; } diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/dispatcher/src/wlan_tdls_ucfg_api.c index e1936cfc62..cd86729d8a 100644 --- a/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/dispatcher/src/wlan_tdls_ucfg_api.c @@ -825,7 +825,8 @@ QDF_STATUS ucfg_tdls_notify_sta_connect( notify = qdf_mem_malloc(sizeof(*notify)); if (!notify) { - wlan_objmgr_vdev_release_ref(notify->vdev, WLAN_TDLS_NB_ID); + wlan_objmgr_vdev_release_ref(notify_info->vdev, + WLAN_TDLS_NB_ID); return QDF_STATUS_E_NULL_VALUE; } From 21a51732582403984bc4a59f580dbb38f257d684 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Fri, 2 Nov 2018 15:14:44 +0530 Subject: [PATCH 88/89] qcacmn: Set TDLS channel offset correctly Set TDLS channel offset correctly when TDLSSECONDARYCHANNELOFFSET command is sent with offset 20. Change-Id: Ifac48da3fea0c83415f3d30caa2919a559f5c3c5 CRs-Fixed: 2341883 --- core/src/wlan_tdls_ct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/wlan_tdls_ct.c b/core/src/wlan_tdls_ct.c index d2fa6bb71a..f62a5e1fd9 100644 --- a/core/src/wlan_tdls_ct.c +++ b/core/src/wlan_tdls_ct.c @@ -975,7 +975,7 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc, return -ENOTSUPP; } - tdls_soc->tdls_channel_offset = 0; + tdls_soc->tdls_channel_offset = BW_INVALID; switch (offchanoffset) { case TDLS_SEC_OFFCHAN_OFFSET_0: @@ -1054,7 +1054,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, switch (offchanmode) { case ENABLE_CHANSWITCH: if (tdls_soc->tdls_off_channel && - tdls_soc->tdls_channel_offset) { + tdls_soc->tdls_channel_offset != BW_INVALID) { chan_switch_params.tdls_off_ch = tdls_soc->tdls_off_channel; chan_switch_params.tdls_off_ch_bw_offset = From 92728a078f8058ca2fa2366d99ee9d903a8381b5 Mon Sep 17 00:00:00 2001 From: Linux Build Service Account Date: Tue, 4 Dec 2018 15:47:36 +0530 Subject: [PATCH 89/89] Move umac/tdls to components/tdls Change-Id: I12eedee6215337be7f5dbcf6d546910cecedd3c3 --- {core => components/tdls/core}/src/wlan_tdls_cmds_process.c | 0 {core => components/tdls/core}/src/wlan_tdls_cmds_process.h | 0 {core => components/tdls/core}/src/wlan_tdls_ct.c | 0 {core => components/tdls/core}/src/wlan_tdls_ct.h | 0 {core => components/tdls/core}/src/wlan_tdls_main.c | 0 {core => components/tdls/core}/src/wlan_tdls_main.h | 0 {core => components/tdls/core}/src/wlan_tdls_mgmt.c | 0 {core => components/tdls/core}/src/wlan_tdls_mgmt.h | 0 {core => components/tdls/core}/src/wlan_tdls_peer.c | 0 {core => components/tdls/core}/src/wlan_tdls_peer.h | 0 {core => components/tdls/core}/src/wlan_tdls_txrx.c | 0 {core => components/tdls/core}/src/wlan_tdls_txrx.h | 0 {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_cfg_api.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_public_structs.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_tgt_api.h | 0 .../tdls/dispatcher}/inc/wlan_tdls_ucfg_api.h | 0 {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_cfg.c | 0 .../tdls/dispatcher}/src/wlan_tdls_tgt_api.c | 0 .../tdls/dispatcher}/src/wlan_tdls_ucfg_api.c | 0 .../tdls/dispatcher}/src/wlan_tdls_utils_api.c | 0 21 files changed, 0 insertions(+), 0 deletions(-) rename {core => components/tdls/core}/src/wlan_tdls_cmds_process.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_cmds_process.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_ct.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_ct.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_main.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_main.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_mgmt.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_mgmt.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_peer.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_peer.h (100%) rename {core => components/tdls/core}/src/wlan_tdls_txrx.c (100%) rename {core => components/tdls/core}/src/wlan_tdls_txrx.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_cfg_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_public_structs.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_tgt_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/inc/wlan_tdls_ucfg_api.h (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_cfg.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_tgt_api.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_ucfg_api.c (100%) rename {dispatcher => components/tdls/dispatcher}/src/wlan_tdls_utils_api.c (100%) diff --git a/core/src/wlan_tdls_cmds_process.c b/components/tdls/core/src/wlan_tdls_cmds_process.c similarity index 100% rename from core/src/wlan_tdls_cmds_process.c rename to components/tdls/core/src/wlan_tdls_cmds_process.c diff --git a/core/src/wlan_tdls_cmds_process.h b/components/tdls/core/src/wlan_tdls_cmds_process.h similarity index 100% rename from core/src/wlan_tdls_cmds_process.h rename to components/tdls/core/src/wlan_tdls_cmds_process.h diff --git a/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c similarity index 100% rename from core/src/wlan_tdls_ct.c rename to components/tdls/core/src/wlan_tdls_ct.c diff --git a/core/src/wlan_tdls_ct.h b/components/tdls/core/src/wlan_tdls_ct.h similarity index 100% rename from core/src/wlan_tdls_ct.h rename to components/tdls/core/src/wlan_tdls_ct.h diff --git a/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c similarity index 100% rename from core/src/wlan_tdls_main.c rename to components/tdls/core/src/wlan_tdls_main.c diff --git a/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h similarity index 100% rename from core/src/wlan_tdls_main.h rename to components/tdls/core/src/wlan_tdls_main.h diff --git a/core/src/wlan_tdls_mgmt.c b/components/tdls/core/src/wlan_tdls_mgmt.c similarity index 100% rename from core/src/wlan_tdls_mgmt.c rename to components/tdls/core/src/wlan_tdls_mgmt.c diff --git a/core/src/wlan_tdls_mgmt.h b/components/tdls/core/src/wlan_tdls_mgmt.h similarity index 100% rename from core/src/wlan_tdls_mgmt.h rename to components/tdls/core/src/wlan_tdls_mgmt.h diff --git a/core/src/wlan_tdls_peer.c b/components/tdls/core/src/wlan_tdls_peer.c similarity index 100% rename from core/src/wlan_tdls_peer.c rename to components/tdls/core/src/wlan_tdls_peer.c diff --git a/core/src/wlan_tdls_peer.h b/components/tdls/core/src/wlan_tdls_peer.h similarity index 100% rename from core/src/wlan_tdls_peer.h rename to components/tdls/core/src/wlan_tdls_peer.h diff --git a/core/src/wlan_tdls_txrx.c b/components/tdls/core/src/wlan_tdls_txrx.c similarity index 100% rename from core/src/wlan_tdls_txrx.c rename to components/tdls/core/src/wlan_tdls_txrx.c diff --git a/core/src/wlan_tdls_txrx.h b/components/tdls/core/src/wlan_tdls_txrx.h similarity index 100% rename from core/src/wlan_tdls_txrx.h rename to components/tdls/core/src/wlan_tdls_txrx.h diff --git a/dispatcher/inc/wlan_tdls_cfg.h b/components/tdls/dispatcher/inc/wlan_tdls_cfg.h similarity index 100% rename from dispatcher/inc/wlan_tdls_cfg.h rename to components/tdls/dispatcher/inc/wlan_tdls_cfg.h diff --git a/dispatcher/inc/wlan_tdls_cfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_cfg_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_cfg_api.h diff --git a/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h similarity index 100% rename from dispatcher/inc/wlan_tdls_public_structs.h rename to components/tdls/dispatcher/inc/wlan_tdls_public_structs.h diff --git a/dispatcher/inc/wlan_tdls_tgt_api.h b/components/tdls/dispatcher/inc/wlan_tdls_tgt_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_tgt_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_tgt_api.h diff --git a/dispatcher/inc/wlan_tdls_ucfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h similarity index 100% rename from dispatcher/inc/wlan_tdls_ucfg_api.h rename to components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h diff --git a/dispatcher/src/wlan_tdls_cfg.c b/components/tdls/dispatcher/src/wlan_tdls_cfg.c similarity index 100% rename from dispatcher/src/wlan_tdls_cfg.c rename to components/tdls/dispatcher/src/wlan_tdls_cfg.c diff --git a/dispatcher/src/wlan_tdls_tgt_api.c b/components/tdls/dispatcher/src/wlan_tdls_tgt_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_tgt_api.c rename to components/tdls/dispatcher/src/wlan_tdls_tgt_api.c diff --git a/dispatcher/src/wlan_tdls_ucfg_api.c b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_ucfg_api.c rename to components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c diff --git a/dispatcher/src/wlan_tdls_utils_api.c b/components/tdls/dispatcher/src/wlan_tdls_utils_api.c similarity index 100% rename from dispatcher/src/wlan_tdls_utils_api.c rename to components/tdls/dispatcher/src/wlan_tdls_utils_api.c