/*
 * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * 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
 */

#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_authenticated(struct wlan_objmgr_vdev *vdev)
{
	struct wlan_objmgr_peer *peer;
	bool is_authenticated = false;

	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID);
	if (!peer) {
		tdls_err("peer is null");
		return false;
	}

	is_authenticated = wlan_peer_mlme_get_auth_state(peer);
	wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_NB_ID);
	return is_authenticated;
}

/**
 * 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_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);
		}
	}
	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 = 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);

	qdf_mem_zero(tdls_vdev->ct_peer_table,
	       (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 (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 qdf_mac_addr *dest_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;
	struct wlan_objmgr_peer *bss_peer;

	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_is_macaddr_group(dest_mac_addr))
		return;

	if (!qdf_mem_cmp(vdev->vdev_mlme.macaddr, mac_addr,
			 QDF_MAC_ADDR_SIZE))
		return;

	bss_peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID);
	if (bss_peer) {
		if (!qdf_mem_cmp(bss_peer->macaddr, mac_addr,
				 QDF_MAC_ADDR_SIZE)) {
			wlan_objmgr_peer_release_ref(bss_peer, WLAN_TDLS_NB_ID);
			return;
		}
		wlan_objmgr_peer_release_ref(bss_peer, WLAN_TDLS_NB_ID);
	}
	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);
	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;
	struct wlan_objmgr_peer *bss_peer;

	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))
		return;
	bss_peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_NB_ID);
	if (bss_peer) {
		if (!qdf_mem_cmp(bss_peer->macaddr, mac_addr,
				 QDF_MAC_ADDR_SIZE)) {
			wlan_objmgr_peer_release_ref(bss_peer, WLAN_TDLS_NB_ID);
			return;
		}
		wlan_objmgr_peer_release_ref(bss_peer, WLAN_TDLS_NB_ID);
	}

	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);
	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 (!tdls_vdev_obj) {
		tdls_notice("tdls_vdev_obj is NULL");
		return;
	}

	tdls_psoc = wlan_vdev_get_tdls_soc_obj(tdls_vdev_obj->vdev);

	if (!tdls_psoc) {
		tdls_notice("tdls_psoc_obj is NULL");
		return;
	}

	curr_peer = tdls_vdev_obj->curr_candidate;

	if (!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 (temp_peer) {
		tdls_notice(QDF_MAC_ADDR_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 (!tdls_soc) {
		tdls_err("tdls soc is NULL");
		return -EINVAL;
	}

	curr_peer = tdls_get_peer(tdls_vdev, mac);
	if (!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_ADDR_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_ADDR_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_ADDR_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;

	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_err("tdls_soc: %pK", tdls_soc);
		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);

	if (tdls_soc->tdls_dp_vdev_update)
		tdls_soc->tdls_dp_vdev_update(&tdls_soc->soc,
				&curr_peer->peer_mac,
				tdls_soc->tdls_update_dp_vdev_flags,
				false);

	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
 * @peer_mac: peer MAC address
 *
 * 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,
		   struct qdf_mac_addr *peer_mac)
{
	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 (!qdf_mem_cmp(
			    tdls_soc->tdls_conn_info[sta_idx].peer_mac.bytes,
			    peer_mac->bytes, QDF_MAC_ADDR_SIZE)) {
			tdls_debug("tdls peer exists %pM", peer_mac->bytes);
			tdls_soc->tdls_conn_info[sta_idx].index = sta_idx;
			return &tdls_soc->tdls_conn_info[sta_idx];
		}
	}

	tdls_err("tdls peer does not exists");
	return NULL;
}

static void
tdls_ct_process_idle_handler(struct wlan_objmgr_vdev *vdev,
			     struct tdls_conn_info *tdls_info)
{
	struct tdls_peer *curr_peer;
	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 (!tdls_info->valid_entry) {
		tdls_err("peer doesn't exists");
		return;
	}

	curr_peer = tdls_find_peer(tdls_vdev_obj,
		(u8 *) &tdls_info->peer_mac.bytes[0]);

	if (!curr_peer) {
		tdls_err("Invalid tdls idle timer expired");
		return;
	}

	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,
		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_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_ADDR_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 wlan_objmgr_vdev *vdev;
	struct tdls_conn_info *tdls_info;
	struct tdls_soc_priv_obj *tdls_soc_obj;
	uint32_t idx;

	tdls_info = (struct tdls_conn_info *)user_data;
	if (!tdls_info)
		return;

	idx = tdls_info->index;
	if (idx == INVALID_TDLS_PEER_INDEX || idx >= WLAN_TDLS_STA_MAX_NUM)
		return;

	tdls_soc_obj = qdf_container_of(tdls_info, struct tdls_soc_priv_obj,
					tdls_conn_info[idx]);

	vdev = tdls_get_vdev(tdls_soc_obj->soc, WLAN_TDLS_NB_ID);
	if (!vdev) {
		tdls_err("Unable to fetch the vdev");
		return;
	}

	tdls_ct_process_idle_handler(vdev, tdls_info);
	wlan_objmgr_vdev_release_ref(vdev,
				     WLAN_TDLS_NB_ID);
}

/**
 * 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)
{
	/* Don't trigger low rssi tear down here since FW will do it */
	/* 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) {
			struct tdls_conn_info *tdls_info;
			tdls_info = tdls_get_conn_info(tdls_soc,
						       &curr_peer->peer_mac);
			qdf_mc_timer_init(&curr_peer->peer_idle_timer,
					  QDF_TIMER_TYPE_SW,
					  tdls_ct_idle_handler,
					  (void *)tdls_info);
			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_ADDR_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_ADDR_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_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);

	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);
}

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;
}

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 = BW_INVALID;

	switch (offchanoffset) {
	case TDLS_SEC_OFFCHAN_OFFSET_0:
		tdls_soc->tdls_channel_offset = BW20;
		break;
	case TDLS_SEC_OFFCHAN_OFFSET_40PLUS:
		tdls_soc->tdls_channel_offset = BW40_HIGH_PRIMARY;
		break;
	case TDLS_SEC_OFFCHAN_OFFSET_40MINUS:
		tdls_soc->tdls_channel_offset = BW40_LOW_PRIMARY;
		break;
	case TDLS_SEC_OFFCHAN_OFFSET_80:
		tdls_soc->tdls_channel_offset = BW80;
		break;
	case TDLS_SEC_OFFCHAN_OFFSET_160:
		tdls_soc->tdls_channel_offset = BWALL;
		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;
}

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 (wlan_vdev_is_up(vdev) != QDF_STATUS_SUCCESS) {
		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 (!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 != BW_INVALID) {
			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);
			if (!chan_switch_params.oper_class) {
				if (chan_switch_params.tdls_off_ch_bw_offset ==
				    BW40_HIGH_PRIMARY)
					chan_switch_params.oper_class =
					tdls_find_opclass(tdls_soc->soc,
						chan_switch_params.tdls_off_ch,
						BW40_LOW_PRIMARY);
				else if (chan_switch_params.
					 tdls_off_ch_bw_offset ==
					 BW40_LOW_PRIMARY)
					chan_switch_params.oper_class =
					tdls_find_opclass(tdls_soc->soc,
						chan_switch_params.tdls_off_ch,
						BW40_HIGH_PRIMARY);
				tdls_debug("oper_class:%d",
					    chan_switch_params.oper_class);
			}
		} 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_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,
		 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 (!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;
}

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
 * @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)
{
	struct wlan_objmgr_peer *peer;
	struct tdls_del_all_tdls_peers *del_msg;
	struct scheduler_msg msg = {0};
	QDF_STATUS status;

	peer = wlan_objmgr_vdev_try_get_bsspeer(vdev, WLAN_TDLS_SB_ID);
	if (!peer) {
		tdls_err("bss peer is null");
		return QDF_STATUS_E_FAILURE;
	}

	del_msg = qdf_mem_malloc(sizeof(*del_msg));
	if (!del_msg) {
		tdls_err("memory alloc failed");
		wlan_objmgr_peer_release_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);

	wlan_objmgr_peer_release_ref(peer, WLAN_TDLS_SB_ID);

	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;
	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);
	}

	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;
	uint8_t vdev_id;
	bool tdls_in_progress = false;

	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 (tdls_is_progress(tdls_vdev, NULL, 0))
		tdls_in_progress = true;

	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");
			tdls_send_update_to_fw(tdls_vdev, tdls_soc, true,
					       true, false, vdev_id);
		}
		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].valid_entry)
			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 %pM",
			    curr_peer->peer_mac.bytes);

		/* 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_peer)
			tdls_soc->tdls_dereg_peer(
					tdls_soc->tdls_peer_context,
					wlan_vdev_get_id(vdev),
					&curr_peer->peer_mac);
		tdls_decrement_peer_count(tdls_soc);
		tdls_soc->tdls_conn_info[staidx].valid_entry = false;
		tdls_soc->tdls_conn_info[staidx].session_id = 255;
		tdls_soc->tdls_conn_info[staidx].index =
						INVALID_TDLS_PEER_INDEX;

		qdf_mem_zero(&tdls_soc->tdls_conn_info[staidx].peer_mac,
			     sizeof(struct qdf_mac_addr));
	}
}

void tdls_teardown_connections(struct wlan_objmgr_psoc *psoc)
{
	struct tdls_osif_indication indication;
	struct tdls_soc_priv_obj *tdls_soc;
	struct wlan_objmgr_vdev *tdls_vdev;


	tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc);
	if (!tdls_soc)
		return;

	/* Get the tdls specific vdev and clear the links */
	tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID);
	if (!tdls_vdev) {
		tdls_err("Unable get the vdev");
		return;
	}
	tdls_disable_offchan_and_teardown_links(tdls_vdev);

	indication.vdev = tdls_vdev;

	if (tdls_soc->tdls_event_cb)
		tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data,
				     TDLS_EVENT_TEARDOWN_LINKS_DONE,
				     &indication);
	wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_SB_ID);
}
