blob: 0d6e8a3d625cd5b167e6f74110d09edba6b2b76e [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Atul Mittal115287b2014-07-08 13:26:33 +05302 * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
Gopichand Nakkala0c1331e2013-01-07 22:49:07 -080020 */
Kiet Lam842dad02014-02-18 18:44:02 -080021
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
Kiran V1ccee932012-12-12 14:49:46 -080028/**========================================================================
29
30 \file wlan_hdd_tdls.c
31
Chilam NG571c65a2013-01-19 12:27:36 +053032 \brief WLAN Host Device Driver implementation for TDLS
Kiran V1ccee932012-12-12 14:49:46 -080033
Kiran V1ccee932012-12-12 14:49:46 -080034 ========================================================================*/
35
36#include <wlan_hdd_includes.h>
37#include <wlan_hdd_hostapd.h>
38#include <net/cfg80211.h>
39#include <linux/netdevice.h>
40#include <linux/skbuff.h>
Chilam NG571c65a2013-01-19 12:27:36 +053041#include <linux/list.h>
Kiran V1ccee932012-12-12 14:49:46 -080042#include <linux/etherdevice.h>
43#include <net/ieee80211_radiotap.h>
44#include "wlan_hdd_tdls.h"
Chilam NG571c65a2013-01-19 12:27:36 +053045#include "wlan_hdd_cfg80211.h"
Mahesh A Saptasagar8b231b32014-08-11 11:58:15 +053046#include "vos_sched.h"
Chilam NG571c65a2013-01-19 12:27:36 +053047
Gopichand Nakkala4327a152013-03-04 23:22:42 -080048static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
49static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
50static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +053051static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Sunil Dutt41de4e22013-11-14 18:09:02 +053052int wpa_tdls_is_allowed_force_peer(tdlsCtx_t *pHddTdlsCtx, u8 *mac);
Hoonki Leed37cbb32013-04-20 00:31:14 -070053#ifdef CONFIG_TDLS_IMPLICIT
54static void wlan_hdd_tdls_pre_setup(struct work_struct *work);
55#endif
Chilam NG571c65a2013-01-19 12:27:36 +053056
Hoonki Lee5a4b2172013-01-29 01:45:53 -080057#ifndef WLAN_FEATURE_TDLS_DEBUG
58#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
59#else
60#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN
61#endif
62
Hoonki Lee387663d2013-02-05 18:08:43 -080063static u8 wlan_hdd_tdls_hash_key (u8 *mac)
Hoonki Leef63df0d2013-01-16 19:29:14 -080064{
65 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -080066 u8 key = 0;
67
68 for (i = 0; i < 6; i++)
69 key ^= mac[i];
70
71 return key;
72}
73
Hoonki Leed37cbb32013-04-20 00:31:14 -070074#ifdef CONFIG_TDLS_IMPLICIT
75static void wlan_hdd_tdls_pre_setup_init_work(tdlsCtx_t * pHddTdlsCtx,
76 hddTdlsPeer_t *curr_candidate)
77{
78 if (TDLS_CTX_MAGIC != pHddTdlsCtx->magic)
79 {
80 pHddTdlsCtx->curr_candidate = curr_candidate;
81 pHddTdlsCtx->magic = TDLS_CTX_MAGIC;
82
Hoonki Leed37cbb32013-04-20 00:31:14 -070083 schedule_work(&pHddTdlsCtx->implicit_setup);
84 }
85}
86#endif
87
Gopichand Nakkala4327a152013-03-04 23:22:42 -080088static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx,
89 tANI_BOOLEAN mutexLock,
90 v_U32_t discoveryExpiry)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080091{
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080092 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053093 hdd_context_t *pHddCtx;
94
c_hpothu7f63e882013-10-02 19:13:35 +053095 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
96 {
97 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
98 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053099 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530100 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530101
102 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
103
c_hpothu7f63e882013-10-02 19:13:35 +0530104 if(0 != (wlan_hdd_validate_context(pHddCtx)))
105 {
106 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
107 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530108 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530109 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800110
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800111 if ( mutexLock )
112 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530113 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800114 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800115
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800116 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700117#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700118 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
119 &pHddTdlsCtx->peerDiscoverTimer,
120 discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700121#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
123 pHddTdlsCtx->ap_rssi);
124
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800125 if ( mutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530126 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800127
128 return;
129}
130
Hoonki Leed37cbb32013-04-20 00:31:14 -0700131#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Hoonki Lee387663d2013-02-05 18:08:43 -0800132static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
133{
134 int i;
135 struct list_head *head;
136 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530137 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800138 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530139 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800140 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800141 int discover_req_sent = 0;
142 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800143 tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800144
c_hpothu7f63e882013-10-02 19:13:35 +0530145 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
146 {
147 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
148 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530149 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530150 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530151
Sushant Kaushik15c4c522014-08-14 12:24:49 +0530152 if (WLAN_HDD_ADAPTER_MAGIC != pHddTdlsCtx->pAdapter->magic)
153 {
154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
155 FL("pAdapter has invalid magic"));
156 return;
157 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530158 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
159
c_hpothu7f63e882013-10-02 19:13:35 +0530160 if(0 != (wlan_hdd_validate_context(pHddCtx)))
161 {
162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
163 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530164 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530165 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530166
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530167 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800168
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800169 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800170
Hoonki Lee387663d2013-02-05 18:08:43 -0800171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
172
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800173 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800174 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800175
Chilam NG571c65a2013-01-19 12:27:36 +0530176 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800177 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530178
Hoonki Lee387663d2013-02-05 18:08:43 -0800179 list_for_each (pos, head) {
180 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530181
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800182 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800183 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
184 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800185 curr_peer->discovery_processed,
186 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800187 curr_peer->tdls_support,
188 curr_peer->link_status,
189 curr_peer->discovery_attempt,
190 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800191
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800192 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
193 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530194
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800195 curr_peer->discovery_processed = 1;
196 discover_req_sent++;
197 pHddTdlsCtx->discovery_peer_cnt--;
198
199 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800200 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800201 (curr_peer->tx_pkt >=
202 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800203
204 if (curr_peer->discovery_attempt <
205 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800206 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
207 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800208 curr_peer->peerMac,
209 WLAN_TDLS_DISCOVERY_REQUEST,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +0530210 1, 0, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800211 curr_peer->discovery_attempt++;
212 }
213 else
214 {
215 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
216 "%s: Maximum Discovery retries reached", __func__);
217 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
218 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800219
220 }
221 }
Chilam NG571c65a2013-01-19 12:27:36 +0530222 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800223 else
224 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800225 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800226 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800227exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800228
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800229 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
230 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
231 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
232 pHddTdlsCtx->discovery_peer_cnt);
233 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800234 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800235 goto done;
236 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800237 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
238
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800239 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530240
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530241 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -0700242
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800243 /* Commenting out the following function as it was introducing
244 * a race condition when pHddTdlsCtx is deleted. Also , this
245 * function is consuming more time in the timer callback.
246 * RSSI based trigger needs to revisit this part of the code.
247 */
248
249 /*
250 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
251 */
Chilam NG571c65a2013-01-19 12:27:36 +0530252
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800253done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800254 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800255
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800256 if ( !doMutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530257 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800258 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800259}
Hoonki Leed37cbb32013-04-20 00:31:14 -0700260#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530261
Hoonki Lee387663d2013-02-05 18:08:43 -0800262static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530263{
264 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800265 struct list_head *head;
266 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530267 hddTdlsPeer_t *curr_peer;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530268 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
269 hdd_context_t *pHddCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800270
c_hpothu7f63e882013-10-02 19:13:35 +0530271 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
272 {
273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
274 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530275 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530276 }
Sushant Kaushik15c4c522014-08-14 12:24:49 +0530277 if (WLAN_HDD_ADAPTER_MAGIC != pHddTdlsCtx->pAdapter->magic)
278 {
279 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
280 FL("pAdapter has invalid magic"));
281 return;
282 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530283 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
284
c_hpothu7f63e882013-10-02 19:13:35 +0530285 if(0 != (wlan_hdd_validate_context(pHddCtx)))
286 {
287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
288 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530289 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530290 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530291
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530292 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800293
Chilam NG571c65a2013-01-19 12:27:36 +0530294 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800295 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530296
Hoonki Lee387663d2013-02-05 18:08:43 -0800297 list_for_each (pos, head) {
298 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530299
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800300 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700301 "%s: " MAC_ADDRESS_STR " link_status %d"
302 " tdls_support %d", __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700303 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800304
Chilam NG571c65a2013-01-19 12:27:36 +0530305 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800306 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700307 "tx %d, rx %d (thr.pkt %d/idle %d), rssi %d (thr.trig %d/hys %d/tear %d)",
308 curr_peer->tx_pkt, curr_peer->rx_pkt,
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800309 pHddTdlsCtx->threshold_config.tx_packet_n,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700310 pHddTdlsCtx->threshold_config.idle_packet_n,
311 curr_peer->rssi,
312 pHddTdlsCtx->threshold_config.rssi_trigger_threshold,
313 pHddTdlsCtx->threshold_config.rssi_hysteresis,
314 pHddTdlsCtx->threshold_config.rssi_teardown_threshold);
Chilam Ng01120412013-02-19 18:32:21 -0800315
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800316 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
317 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530318
319 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
320 (FALSE == curr_peer->isForcedPeer)) {
321 continue;
322 }
323
Chilam NG571c65a2013-01-19 12:27:36 +0530324 if (curr_peer->tx_pkt >=
325 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800326
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800327 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800328 {
329
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700330 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530331#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leed37cbb32013-04-20 00:31:14 -0700332 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530333#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800334 }
335 else
336 {
337 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800338 "%s: Maximum peer connected already! %d",
339 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800340 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800341 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530342 }
Hoonki Leefb8df672013-04-10 18:20:34 -0700343 }
344 else if (eTDLS_LINK_CONNECTED == curr_peer->link_status) {
Chilam Ng01120412013-02-19 18:32:21 -0800345 if ((tANI_S32)curr_peer->rssi <
346 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800347
Chilam Ng01120412013-02-19 18:32:21 -0800348 VOS_TRACE( VOS_MODULE_ID_HDD,
349 VOS_TRACE_LEVEL_WARN,
350 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
351 MAC_ADDR_ARRAY(curr_peer->peerMac));
352#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700353 wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
354 curr_peer,
355 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Chilam Ng01120412013-02-19 18:32:21 -0800356#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800357 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530358 }
Chilam Ng01120412013-02-19 18:32:21 -0800359
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530360 /* Only teardown based on non zero idle packet threshold, to address a use
361 * case where this threshold does not get consider for TEAR DOWN.
362 */
363
364 if (( 0 != pHddTdlsCtx->threshold_config.idle_packet_n ) &&
365 ((curr_peer->tx_pkt <
Chilam Ng01120412013-02-19 18:32:21 -0800366 pHddTdlsCtx->threshold_config.idle_packet_n) &&
367 (curr_peer->rx_pkt <
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530368 pHddTdlsCtx->threshold_config.idle_packet_n))) {
Chilam Ng01120412013-02-19 18:32:21 -0800369 if (VOS_TIMER_STATE_RUNNING !=
370 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
372 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
373 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700374 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
375 &curr_peer->peerIdleTimer,
376 pHddTdlsCtx->threshold_config.idle_timeout_t);
Chilam Ng01120412013-02-19 18:32:21 -0800377 }
378 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800379 if (VOS_TIMER_STATE_RUNNING ==
380 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
382 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
383 MAC_ADDR_ARRAY(curr_peer->peerMac));
384 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800385 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800386 }
Chilam Ng01120412013-02-19 18:32:21 -0800387
Hoonki Leecdd8e962013-01-20 00:45:46 -0800388// if (curr_peer->rssi <
389// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
390// pHddTdlsCtx->ap_rssi)) {
391//
392//#ifdef CONFIG_TDLS_IMPLICIT
393// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
394// curr_peer->peerMac,
395// NL80211_TDLS_TEARDOWN, FALSE,
396// GFP_KERNEL);
397//#endif
398// }
Chilam NG571c65a2013-01-19 12:27:36 +0530399 }
Chilam Ng01120412013-02-19 18:32:21 -0800400 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530401
402 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
403 (FALSE == curr_peer->isForcedPeer)) {
404 continue;
405 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700406 if (!TDLS_IS_CONNECTED(curr_peer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800407 if (curr_peer->tx_pkt >=
408 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800409
Sunil Duttb0d39242014-09-10 23:54:51 +0530410 /* Ignore discovery attempt if External Control is enabled, that
411 * is, peer is forced. In that case, continue discovery attempt
412 * regardless attempt count
413 */
414 if (curr_peer->isForcedPeer || curr_peer->discovery_attempt++ <
Chilam Ng01120412013-02-19 18:32:21 -0800415 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700416 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Hoonki Leed37cbb32013-04-20 00:31:14 -0700417#ifdef CONFIG_TDLS_IMPLICIT
418 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
419#endif
Chilam Ng01120412013-02-19 18:32:21 -0800420 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800421 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800422 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800423 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Atul Mittal115287b2014-07-08 13:26:33 +0530424 wlan_hdd_tdls_set_peer_link_status(
425 curr_peer,
426 eTDLS_LINK_IDLE,
427 eTDLS_LINK_NOT_SUPPORTED);
428
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800429 }
Chilam Ng01120412013-02-19 18:32:21 -0800430 }
431 }
Chilam NG571c65a2013-01-19 12:27:36 +0530432 }
433
Hoonki Leecdd8e962013-01-20 00:45:46 -0800434next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530435 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800436 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800437 }
Chilam NG571c65a2013-01-19 12:27:36 +0530438 }
439
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700440 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
441 &pHddTdlsCtx->peerUpdateTimer,
442 pHddTdlsCtx->threshold_config.tx_period_t);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530443 mutex_unlock(&pHddCtx->tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530444}
445
Chilam Ng1279e232013-01-25 15:06:52 -0800446static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
447{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800448#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800449 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530450 tdlsCtx_t *pHddTdlsCtx;
451 hdd_context_t *pHddCtx;
Chilam Ng1279e232013-01-25 15:06:52 -0800452
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700453 if (NULL == curr_peer)
454 {
455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530456 FL("Invalid tdls idle timer expired"));
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700457 return;
458 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530459 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
460
461 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530462 {
463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
464 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530465 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530466 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530467
468 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
469
c_hpothu7f63e882013-10-02 19:13:35 +0530470 if(0 != (wlan_hdd_validate_context(pHddCtx)))
471 {
472 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
473 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530474 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530475 }
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700476
477 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800478 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d",
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700479 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
480 curr_peer->tx_pkt,
481 curr_peer->rx_pkt,
482 curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n);
483
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530484 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800485
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700486 /* Check tx/rx statistics on this tdls link for recent activities and
487 * then decide whether to tear down the link or keep it.
488 */
489 if ((curr_peer->tx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n) || (curr_peer->rx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n))
490 {
491 /* this tdls link got back to normal, so keep it */
492 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
493 "%s: tdls link to " MAC_ADDRESS_STR " back to normal, will stay",
494 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
495 }
496 else
497 {
498 /* this tdls link needs to get torn down */
499 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
500 "%s: trigger tdls link to " MAC_ADDRESS_STR " down",
501 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
502
503 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
504 curr_peer,
505 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
506 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530507 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800508#endif
509}
510
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700511static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
512{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700513 int i;
514 struct list_head *head;
515 hddTdlsPeer_t *tmp;
516 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700517 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530518 hdd_context_t *pHddCtx;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700519
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530520 pHddTdlsCtx = (tdlsCtx_t *)userData;
521
522 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530523 {
524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
525 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530526 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530527 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530528
Sushant Kaushik15c4c522014-08-14 12:24:49 +0530529 if (WLAN_HDD_ADAPTER_MAGIC != pHddTdlsCtx->pAdapter->magic)
530 {
531 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
532 FL("pAdapter has invalid magic"));
533 return;
534 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530535 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
536
c_hpothu7f63e882013-10-02 19:13:35 +0530537 if(0 != (wlan_hdd_validate_context(pHddCtx)))
538 {
539 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
540 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530541 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530542 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530543
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530544 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700545
546 for (i = 0; i < 256; i++) {
547 head = &pHddTdlsCtx->peer_list[i];
548 list_for_each_safe (pos, q, head) {
549 tmp = list_entry(pos, hddTdlsPeer_t, node);
550 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
551 {
552 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
553 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
554 MAC_ADDR_ARRAY(tmp->peerMac));
Atul Mittal115287b2014-07-08 13:26:33 +0530555 wlan_hdd_tdls_set_peer_link_status(
556 tmp,
557 eTDLS_LINK_IDLE,
Atul Mittalad630e42014-10-07 19:19:14 +0530558 eTDLS_LINK_NOT_SUPPORTED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700559 }
560 }
561 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700562
563 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700564 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700565
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530566 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700567
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700568 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
569
570 return;
571}
572
Hoonki Lee14621352013-04-16 17:51:19 -0700573static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
574{
575 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
576 tdlsCtx_t *pHddTdlsCtx;
577
578 if ( NULL == curr_peer )
c_hpothu7f63e882013-10-02 19:13:35 +0530579 {
580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
581 FL("curr_peer is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700582 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530583 }
Hoonki Lee14621352013-04-16 17:51:19 -0700584
585 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
586
587 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +0530588 {
589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
590 FL("pHddTdlsCtx is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700591 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530592 }
Hoonki Lee14621352013-04-16 17:51:19 -0700593
594 WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext,
595 (v_U8_t *)&curr_peer->staId);
596}
597
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800598static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800599{
600 int i;
601 struct list_head *head;
602 hddTdlsPeer_t *tmp;
603 struct list_head *pos, *q;
604
c_hpothu7f63e882013-10-02 19:13:35 +0530605 if (NULL == pHddTdlsCtx)
606 {
607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
608 FL("pHddTdlsCtx is NULL"));
609 return;
610 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800611
612 for (i = 0; i < 256; i++) {
613 head = &pHddTdlsCtx->peer_list[i];
614 list_for_each_safe (pos, q, head) {
615 tmp = list_entry(pos, hddTdlsPeer_t, node);
616 list_del(pos);
617 vos_mem_free(tmp);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800618 tmp = NULL;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800619 }
620 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800621}
622
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700623static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
624{
625 tdls_scan_context_t *scan_ctx =
626 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
627
628 if (NULL == scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +0530629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 FL("scan_ctx is NULL"));
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700632 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530633 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700634
635 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
636 return;
637
638 scan_ctx->attempt++;
639
640 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
641#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
642 scan_ctx->dev,
643#endif
644 scan_ctx->scan_request);
645}
646
Pradeep Reddy POTTETIf0569d72014-12-13 16:54:03 +0530647void wlan_hdd_tdls_btCoex_cb(void *data, int indType)
648{
649 hdd_adapter_t *pAdapter;
650 hdd_context_t *pHddCtx;
651 u16 connectedTdlsPeers;
652 tdlsCtx_t *pHddTdlsCtx;
653 hddTdlsPeer_t *currPeer;
654 hdd_scaninfo_t *pScanInfo;
655
656 if ((NULL == data) || (indType < 0))
657 {
658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
659 FL("Invalid arguments"));
660 return;
661 }
662
663 pHddCtx = (hdd_context_t *)data;
664 if (0 != (wlan_hdd_validate_context(pHddCtx)))
665 {
666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
667 FL("pHddCtx is not valid"));
668 return;
669 }
670
671 /* if tdls is not enabled, then continue btCoex */
672 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
673 {
674 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
675 FL("tdls is not enabled"));
676 return;
677 }
678
679 /* get pAdapter context, do we need WLAN_HDD_P2P_CLIENT */
680 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
681 if (NULL == pAdapter)
682 {
683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
684 FL("pAdapter is not valid"));
685 return;
686 }
687
688 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
689 if (NULL == pHddTdlsCtx)
690 {
691 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
692 FL("pHddTdlsCtx is not valid"));
693 return;
694 }
695
696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
697 "%s: BtCoex notification type %d", __func__, indType);
698 /* BtCoex notification type enabled, Disable TDLS */
699 if (indType == SIR_COEX_IND_TYPE_TDLS_DISABLE)
700 {
701 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
702 FL("BtCoex notification, Disable TDLS"));
703
704 pScanInfo = &pHddCtx->scan_info;
705 // Lets do abort scan if scan is pending
706 if ((pScanInfo != NULL) && pScanInfo->mScanPending)
707 {
708 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
709 eCSR_SCAN_ABORT_DEFAULT);
710 }
711
712 /* tdls is in progress */
713 currPeer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
714 if (NULL != currPeer)
715 {
716 wlan_hdd_tdls_set_peer_link_status (currPeer,
717 eTDLS_LINK_IDLE,
718 eTDLS_LINK_UNSPECIFIED);
719 }
720
721 /* while tdls is up */
722 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
723 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
724 {
725 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
726 /* disable implicit trigger logic & tdls operatoin */
727 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
728 pHddCtx->is_tdls_btc_enabled = FALSE;
729
730 /* teardown the peers on the btcoex */
731 if (connectedTdlsPeers)
732 {
733 tANI_U8 staIdx;
734 hddTdlsPeer_t *curr_peer;
735
736 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
737 {
738 if (pHddCtx->tdlsConnInfo[staIdx].staId)
739 {
740 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
741 ("%s: indicate TDLS teadown (staId %d)"),
742 __func__,pHddCtx->tdlsConnInfo[staIdx].staId);
743
744 #ifdef CONFIG_TDLS_IMPLICIT
745 curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx,
746 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
747 if(curr_peer) {
748 wlan_hdd_tdls_indicate_teardown(
749 curr_peer->pHddTdlsCtx->pAdapter, curr_peer,
750 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
751 }
752 #endif
753 }
754 }
755 }
756 }
757 }
758 /* BtCoex notification type enabled, Enable TDLS */
759 else if (indType == SIR_COEX_IND_TYPE_TDLS_ENABLE)
760 {
761 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
762 FL("BtCoex notification, Enable TDLS"));
763 /* if tdls was enabled before btCoex, re-enable tdls mode */
764 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
765 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
766 {
767 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
768 ("%s: revert tdls mode %d"), __func__,
769 pHddCtx->tdls_mode_last);
770 pHddCtx->is_tdls_btc_enabled = TRUE;
771 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
772 }
773 }
774 return;
775}
776
Agarwal Ashish4b87f922014-06-18 03:03:21 +0530777/* initialize TDLS global context */
778void wlan_hdd_tdls_init(hdd_context_t *pHddCtx )
779{
780 v_U8_t staIdx;
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700781
Agarwal Ashish4b87f922014-06-18 03:03:21 +0530782 pHddCtx->connected_peer_count = 0;
783
784 pHddCtx->tdls_scan_ctxt.magic = 0;
785 pHddCtx->tdls_scan_ctxt.attempt = 0;
786 pHddCtx->tdls_scan_ctxt.reject = 0;
787 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
788
789 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
790 {
791 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
792 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
793 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
794 sizeof(v_MACADDR_t)) ;
795 }
Pradeep Reddy POTTETIf0569d72014-12-13 16:54:03 +0530796 pHddCtx->is_tdls_btc_enabled = TRUE;
797 sme_RegisterBtCoexTDLSCallback(pHddCtx->hHal, wlan_hdd_tdls_btCoex_cb);
Agarwal Ashish4b87f922014-06-18 03:03:21 +0530798
799 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
800 {
801 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
803 }
804 else
805 {
806 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
807 }
808}
809
810int wlan_hdd_sta_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800811{
Chilam Ng01120412013-02-19 18:32:21 -0800812 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700813 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800814 int i;
Sunil Dutt66485cb2013-12-19 19:05:03 +0530815 if (NULL == pHddCtx)
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +0530816 {
817 hddLog(VOS_TRACE_LEVEL_ERROR, "%s pHddCtx is NULL", __func__);
Sunil Dutt66485cb2013-12-19 19:05:03 +0530818 return -1;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +0530819 }
Sunil Dutt66485cb2013-12-19 19:05:03 +0530820
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530821 if (test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
822 {
823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
824 "%s: TDLS INIT DONE set to 1, return success to the caller", __func__);
825 return 0;
826 }
Sunil Dutt66485cb2013-12-19 19:05:03 +0530827
Hoonki Lee27511902013-03-14 18:19:06 -0700828 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
829 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
830 {
831 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
832 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
833 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
834 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
835 sme_IsFeatureSupportedByFW(TDLS));
836 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800837 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530838 /* TDLS is supported only in STA / P2P Client modes,
839 * hence the check for TDLS support in a specific Device mode.
840 * Do not return a failure rather do not continue further
841 * with the initialization as tdls_init would be called
842 * during the open adapter for a p2p interface at which point
843 * the device mode would be a P2P_DEVICE. The point here is to
844 * continue initialization for STA / P2P Client modes.
845 * TDLS exit also check for the device mode for clean up hence
846 * there is no issue even if success is returned.
847 */
848 if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter))
849 {
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +0530850 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS is not supported in mode : %d", __func__, pAdapter->device_mode);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530851 return 0;
852 }
853 /* Check for the valid pHddTdlsCtx. If valid do not further
854 * allocate the memory, rather continue with the initialization.
855 * If tdls_initialization would get reinvoked without tdls_exit
856 * getting invoked (SSR) there is no point to further proceed
857 * with the memory allocations.
858 */
859 if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx)
860 {
861 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800862
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530863 if (NULL == pHddTdlsCtx) {
864 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
865 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
Sunil Dutt66485cb2013-12-19 19:05:03 +0530866 mutex_unlock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530867 return -1;
868 }
869 /* initialize TDLS pAdater context */
870 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
871#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
872 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
873 VOS_TIMER_TYPE_SW,
874 wlan_hdd_tdls_discover_peer_cb,
875 pHddTdlsCtx);
876#endif
Hoonki Lee27511902013-03-14 18:19:06 -0700877
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530878 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
879 VOS_TIMER_TYPE_SW,
880 wlan_hdd_tdls_update_peer_cb,
881 pHddTdlsCtx);
882 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
883 VOS_TIMER_TYPE_SW,
884 wlan_hdd_tdls_discovery_timeout_peer_cb,
885 pHddTdlsCtx);
886
887 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700888 }
889
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530890 pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700891
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700892 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700893
Hoonki Lee27511902013-03-14 18:19:06 -0700894 pHddTdlsCtx->pAdapter = pAdapter;
895
896 for (i = 0; i < 256; i++)
897 {
898 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
899 }
900
Hoonki Leed37cbb32013-04-20 00:31:14 -0700901 pHddTdlsCtx->curr_candidate = NULL;
902 pHddTdlsCtx->magic = 0;
903
Hoonki Lee27511902013-03-14 18:19:06 -0700904 /* remember configuration even if it is not used right now. it could be used later */
905 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
906 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
907 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
908 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
909 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
910 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
911 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
912 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
913 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530914
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700915 INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
916 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530917 set_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
Hoonki Lee27511902013-03-14 18:19:06 -0700918
919 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530920}
921
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800922void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530923{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800924 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700925 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800926
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530927 /*
928 * NOTE: The Callers of this function should ensure to acquire the
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530929 * tdls_lock to avoid any concurrent access to the Adapter and logp
930 * protection has to be ensured.
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530931 */
932
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530933 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +0530934
935 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530936 {
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +0530937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
938 "%s: HDD context is Null", __func__);
939 return ;
940 }
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530941 if (!test_bit(TDLS_INIT_DONE, &pAdapter->event_flags))
Agarwal Ashish9ffa5b92014-11-18 21:07:02 +0530942 {
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530943 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
944 "%s: TDLS INIT DONE set to 0, no point in exit", __func__);
945 return;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530946 }
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530947 clear_bit(TDLS_INIT_DONE, &pAdapter->event_flags);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530948
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800949 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800950 if (NULL == pHddTdlsCtx)
951 {
c_hpothu7f63e882013-10-02 19:13:35 +0530952 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
953 FL("pHddTdlsCtx is NULL"));
Hoonki Leebfee0342013-01-21 16:43:45 -0800954 return;
955 }
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +0530956
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700957#ifdef WLAN_OPEN_SOURCE
958 cancel_work_sync(&pHddTdlsCtx->implicit_setup);
959 cancel_delayed_work_sync(&pHddCtx->tdls_scan_ctxt.tdls_scan_work);
960#endif
Hoonki Leebfee0342013-01-21 16:43:45 -0800961
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800962 /* must stop timer here before freeing peer list, because peerIdleTimer is
963 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800964 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
965 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800966
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700967 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
Sushant Kaushik15c4c522014-08-14 12:24:49 +0530968 pHddTdlsCtx->magic = 0;
969 pHddTdlsCtx->pAdapter = NULL;
Chilam Nga75d8b62013-01-29 01:35:59 -0800970 vos_mem_free(pHddTdlsCtx);
Pradeep Reddy POTTETI59c90d62014-03-24 19:45:47 +0530971 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
Chilam Nga75d8b62013-01-29 01:35:59 -0800972 pHddTdlsCtx = NULL;
Chilam NG571c65a2013-01-19 12:27:36 +0530973}
974
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530975/* stop all monitoring timers per Adapter */
976static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800977{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700978#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800979 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700980#endif
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800981 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700982 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530983}
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800984
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530985/* stop all per peer timers */
986static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx)
987{
988 int i;
989 struct list_head *head;
990 struct list_head *pos;
991 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800992 for (i = 0; i < 256; i++)
993 {
994 head = &pHddTdlsCtx->peer_list[i];
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800995 list_for_each (pos, head) {
996 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800997 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800998 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800999 __func__,
Chilam Ng01120412013-02-19 18:32:21 -08001000 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001001 vos_timer_stop ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -07001002 vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001003 }
1004 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001005}
1006
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301007/* stop all the tdls timers running */
1008static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001009{
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301010 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
1011 wlan_hdd_tdls_peer_timers_stop(pHddTdlsCtx);
1012}
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001013
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301014static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
1015{
Hoonki Leed37cbb32013-04-20 00:31:14 -07001016#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001017 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
1018 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -07001019#endif
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001020 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
1021 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001022 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
1023 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301024}
1025/*Free all the timers related to the TDLS peer */
1026static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
1027{
1028 int i;
1029 struct list_head *head;
1030 struct list_head *pos;
1031 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001032 for (i = 0; i < 256; i++)
1033 {
1034 head = &pHddTdlsCtx->peer_list[i];
1035
1036 list_for_each (pos, head) {
1037 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1038
1039 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001040 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001041 __func__,
Chilam Ng01120412013-02-19 18:32:21 -08001042 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001043 vos_timer_stop ( &curr_peer->peerIdleTimer );
1044 vos_timer_destroy ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -07001045 vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
1046 vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001047 }
1048 }
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301049
1050}
1051
1052/* destroy all the tdls timers running */
1053static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
1054{
1055 wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx);
1056 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001057}
1058
Hoonki Lee387663d2013-02-05 18:08:43 -08001059/* if mac address exist, return pointer
1060 if mac address doesn't exist, create a list and add, return pointer
1061 return NULL if fails to get new mac address
1062*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001063hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301064{
Hoonki Lee387663d2013-02-05 18:08:43 -08001065 struct list_head *head;
1066 hddTdlsPeer_t *peer;
1067 u8 key;
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001068 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301069 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1070
c_hpothu7f63e882013-10-02 19:13:35 +05301071 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1072 {
1073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1074 FL("pHddCtx is not valid"));
1075 return 0;
1076 }
Hoonki Leebfee0342013-01-21 16:43:45 -08001077
Hoonki Lee387663d2013-02-05 18:08:43 -08001078 /* if already there, just update */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301079 peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -08001080 if (peer != NULL)
1081 {
1082 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +05301083 }
1084
Hoonki Lee387663d2013-02-05 18:08:43 -08001085 /* not found, allocate and add the list */
1086 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
1087 if (NULL == peer) {
1088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
1089 return NULL;
1090 }
Chilam NG571c65a2013-01-19 12:27:36 +05301091
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301092 mutex_lock(&pHddCtx->tdls_lock);
1093
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001094 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1095
1096 if (NULL == pHddTdlsCtx)
1097 {
c_hpothue21931b2014-09-08 14:02:14 +05301098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu7f63e882013-10-02 19:13:35 +05301099 FL("pHddTdlsCtx is NULL"));
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001100 vos_mem_free(peer);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301101 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001102 return NULL;
1103 }
1104
1105 key = wlan_hdd_tdls_hash_key(mac);
1106 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +05301107
Hoonki Lee387663d2013-02-05 18:08:43 -08001108 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
1109 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001110 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -08001111
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001112 vos_timer_init(&peer->peerIdleTimer,
1113 VOS_TIMER_TYPE_SW,
1114 wlan_hdd_tdls_idle_cb,
1115 peer);
1116
Hoonki Lee14621352013-04-16 17:51:19 -07001117 vos_timer_init(&peer->initiatorWaitTimeoutTimer,
1118 VOS_TIMER_TYPE_SW,
1119 wlan_hdd_tdls_initiator_wait_cb,
1120 peer);
1121
Hoonki Lee387663d2013-02-05 18:08:43 -08001122 list_add_tail(&peer->node, head);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301123 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001124
1125 return peer;
1126}
1127
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001128int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -07001129 u8* mac,
1130 tTDLSCapType cap)
1131{
1132 hddTdlsPeer_t *curr_peer;
1133
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001134 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -07001135 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301136 {
1137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1138 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001139 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301140 }
Hoonki Lee27511902013-03-14 18:19:06 -07001141
1142 curr_peer->tdls_support = cap;
1143
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001144 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001145}
1146
Atul Mittal115287b2014-07-08 13:26:33 +05301147void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer,
1148 tTDLSLinkStatus status,
1149 tTDLSLinkReason reason)
Hoonki Lee387663d2013-02-05 18:08:43 -08001150{
Atul Mittal115287b2014-07-08 13:26:33 +05301151 /*EXT TDLS*/
1152 tANI_S32 state = 0;
1153 tANI_S32 res = 0;
1154 /*EXT TDLS*/
Hoonki Lee387663d2013-02-05 18:08:43 -08001155 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301156 {
1157 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1158 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001159 return;
c_hpothu7f63e882013-10-02 19:13:35 +05301160 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001161
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001162 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -08001163 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +05301164
1165 curr_peer->link_status = status;
1166
Atul Mittal115287b2014-07-08 13:26:33 +05301167 /*EXT TDLS*/
1168 if (curr_peer->isForcedPeer && curr_peer->state_change_notification)
1169 {
1170 /*save the reason for any further query*/
1171 curr_peer->reason = reason;
1172 wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res);
1173
1174 (curr_peer->state_change_notification)(
1175 curr_peer->peerMac,
1176 state,
1177 res,
1178 curr_peer->pHddTdlsCtx->pAdapter);
1179
1180 }
1181 /*EXT TDLS*/
1182
Chilam NG571c65a2013-01-19 12:27:36 +05301183}
1184
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001185void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
1186 u8* mac,
Atul Mittal115287b2014-07-08 13:26:33 +05301187 tTDLSLinkStatus linkStatus,
1188 tTDLSLinkReason reason)
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001189{
Atul Mittal115287b2014-07-08 13:26:33 +05301190
1191 /*EXT TDLS*/
1192 tANI_S32 state = 0;
1193 tANI_S32 res = 0;
1194 /*EXT TDLS*/
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001195 hddTdlsPeer_t *curr_peer;
1196
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301197 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001198 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301199 {
1200 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1201 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001202 return;
c_hpothu7f63e882013-10-02 19:13:35 +05301203 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001204
1205 curr_peer->link_status= linkStatus;
1206
Atul Mittal115287b2014-07-08 13:26:33 +05301207 /*EXT TDLS*/
1208
1209 if (curr_peer->isForcedPeer && curr_peer->state_change_notification)
1210 {
1211 /*save the reason for any further query*/
1212 curr_peer->reason = reason;
1213 wlan_hdd_tdls_get_wifi_hal_state(curr_peer, &state, &res);
1214
1215 (*curr_peer->state_change_notification)(mac,
1216 state,
1217 res,
1218 curr_peer->pHddTdlsCtx->pAdapter);
1219
1220 }
1221 /*EXT TDLS*/
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001222 return;
1223}
1224
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001225int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301226{
1227 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001228 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301229 hdd_context_t *pHddCtx;
1230
1231 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +05301232 {
1233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05301234 FL("pHddTdlsCtx is NULL device mode = %d"), pAdapter->device_mode);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301235 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301236 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301237
1238 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1239
c_hpothu7f63e882013-10-02 19:13:35 +05301240 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1241 {
1242 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1243 FL("pHddCtx is not valid"));
1244 return 0;
1245 }
Chilam NG571c65a2013-01-19 12:27:36 +05301246
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001247 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001248
1249 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05301250 {
1251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1252 FL("curr_peer is NULL"));
Hoonki Lee387663d2013-02-05 18:08:43 -08001253 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301254 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001255
1256 if (pHddTdlsCtx->discovery_sent_cnt)
1257 pHddTdlsCtx->discovery_sent_cnt--;
1258
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301259 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301260
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001261 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301262
1263 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001264 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001265 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001266 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001267 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001268
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001269 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001270 "Discovery(%u) Response from " MAC_ADDRESS_STR " link_status %d",
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001271 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
1272 curr_peer->link_status);
1273
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001274 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001275 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001276 /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI
1277 threshold is also met before setting up TDLS link*/
1278 if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold)
1279 {
Atul Mittal115287b2014-07-08 13:26:33 +05301280 wlan_hdd_tdls_set_peer_link_status(curr_peer,
1281 eTDLS_LINK_DISCOVERED,
1282 eTDLS_LINK_SUCCESS);
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001283 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1284 "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" ,
1285 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1286 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
1287 cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL);
1288 }
1289 else
1290 {
1291 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1292 "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ",
1293 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1294 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
Sunil Duttb0d39242014-09-10 23:54:51 +05301295
1296 /* if RSSI threshold is not met then allow further discovery
1297 * attempts by decrementing count for the last attempt
1298 */
1299 if (curr_peer->discovery_attempt)
1300 curr_peer->discovery_attempt--;
1301
Atul Mittal115287b2014-07-08 13:26:33 +05301302 wlan_hdd_tdls_set_peer_link_status(curr_peer,
1303 eTDLS_LINK_IDLE,
1304 eTDLS_LINK_UNSPECIFIED);
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001305 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001306 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001307 else
1308 {
1309 wlan_hdd_tdls_check_bmps(pAdapter);
1310 }
Chilam NG571c65a2013-01-19 12:27:36 +05301311
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001312 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -08001313 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301314}
1315
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301316int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter,
1317 u8 *mac,
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301318 tCsrStaParams *StaParams,
1319 tANI_BOOLEAN isBufSta,
1320 tANI_BOOLEAN isOffChannelSupported)
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301321{
1322 hddTdlsPeer_t *curr_peer;
1323
1324 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1325 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301326 {
1327 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1328 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301329 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301330 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301331
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301332 curr_peer->uapsdQueues = StaParams->uapsd_queues;
1333 curr_peer->maxSp = StaParams->max_sp;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301334 curr_peer->isBufSta = isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301335 curr_peer->isOffChannelSupported = isOffChannelSupported;
1336
1337 vos_mem_copy(curr_peer->supported_channels,
1338 StaParams->supported_channels,
1339 StaParams->supported_channels_len);
1340
1341 curr_peer->supported_channels_len =
1342 StaParams->supported_channels_len;
1343
1344 vos_mem_copy(curr_peer->supported_oper_classes,
1345 StaParams->supported_oper_classes,
1346 StaParams->supported_oper_classes_len);
1347
1348 curr_peer->supported_oper_classes_len =
1349 StaParams->supported_oper_classes_len;
Agarwal Ashish16020c42014-12-29 22:01:11 +05301350 curr_peer->qos = StaParams->capability & CAPABILITIES_QOS_OFFSET;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301351 return 0;
1352}
1353
1354int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac,
1355 tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams)
1356{
1357 hddTdlsPeer_t *curr_peer;
1358
1359 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1360 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301361 {
1362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1363 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301364 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301365 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301366
1367 tdlsLinkEstablishParams->isResponder = curr_peer->is_responder;
1368 tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues;
1369 tdlsLinkEstablishParams->maxSp = curr_peer->maxSp;
1370 tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301371 tdlsLinkEstablishParams->isOffChannelSupported =
1372 curr_peer->isOffChannelSupported;
1373
1374 vos_mem_copy(tdlsLinkEstablishParams->supportedChannels,
1375 curr_peer->supported_channels,
1376 curr_peer->supported_channels_len);
1377
1378 tdlsLinkEstablishParams->supportedChannelsLen =
1379 curr_peer->supported_channels_len;
1380
1381 vos_mem_copy(tdlsLinkEstablishParams->supportedOperClasses,
1382 curr_peer->supported_oper_classes,
1383 curr_peer->supported_oper_classes_len);
1384
1385 tdlsLinkEstablishParams->supportedOperClassesLen =
1386 curr_peer->supported_oper_classes_len;
Agarwal Ashish16020c42014-12-29 22:01:11 +05301387 tdlsLinkEstablishParams->qos = curr_peer->qos;
1388
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301389 return 0;
1390}
1391
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001392int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +05301393{
1394 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +05301395
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301396 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -08001397 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301398 {
1399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1400 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001401 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301402 }
Chilam NG571c65a2013-01-19 12:27:36 +05301403
1404 curr_peer->rssi = rxRssi;
1405
Hoonki Lee387663d2013-02-05 18:08:43 -08001406 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301407}
1408
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001409int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08001410{
1411 hddTdlsPeer_t *curr_peer;
1412
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001413 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001414 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301415 {
1416 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1417 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001418 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301419 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001420
1421 curr_peer->is_responder = responder;
1422
1423 return 0;
1424}
1425
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001426int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -08001427{
1428 hddTdlsPeer_t *curr_peer;
1429
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301430 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001431 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301432 {
1433 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1434 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001435 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301436 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001437
1438 return (curr_peer->is_responder);
1439}
1440
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001441int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001442{
1443 hddTdlsPeer_t *curr_peer;
1444
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001445 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001446 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301447 {
1448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1449 "%s: curr_peer is NULL", __func__);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001450 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301451 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001452
1453 curr_peer->signature = uSignature;
1454
1455 return 0;
1456}
1457
Hoonki Leea34dd892013-02-05 22:56:02 -08001458
Hoonki Lee387663d2013-02-05 18:08:43 -08001459void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301460{
Chilam NG571c65a2013-01-19 12:27:36 +05301461 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +05301462}
1463
Hoonki Lee387663d2013-02-05 18:08:43 -08001464void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -08001465{
Chilam Ng1279e232013-01-25 15:06:52 -08001466 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -08001467}
1468
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001469int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +05301470{
Hoonki Lee387663d2013-02-05 18:08:43 -08001471 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001472 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +05301473
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001474 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
1475 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -08001476
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001477 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001478 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301479 {
c_hpothue21931b2014-09-08 14:02:14 +05301480 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1481 FL("curr_peer is NULL"));
Chilam NG571c65a2013-01-19 12:27:36 +05301482 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301483 }
Chilam NG571c65a2013-01-19 12:27:36 +05301484
Chilam Ng1279e232013-01-25 15:06:52 -08001485 if (tx)
1486 curr_peer->tx_pkt++;
1487 else
1488 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +05301489
Chilam NG571c65a2013-01-19 12:27:36 +05301490 return 0;
1491}
1492
Hoonki Lee27511902013-03-14 18:19:06 -07001493static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
1494{
1495 if (config->tdls > 2)
1496 {
1497 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
1498 return -1;
1499 }
1500 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
1501 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
1502 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001503 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%ld>", __func__, config->tx_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001504 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
1505 return -1;
1506 }
1507 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
1508 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
1509 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001510 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%ld>", __func__, config->tx_packet_n,
Hoonki Lee27511902013-03-14 18:19:06 -07001511 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
1512 return -1;
1513 }
1514 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
1515 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
1516 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001517 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%ld>", __func__, config->discovery_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001518 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
1519 return -1;
1520 }
1521 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
1522 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
1523 {
1524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
1525 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
1526 return -1;
1527 }
1528 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
1529 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
1530 {
1531 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
1532 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
1533 return -1;
1534 }
1535 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
1536 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
1537 {
1538 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
1539 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
1540 return -1;
1541 }
1542 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
1543 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
1544 {
1545 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
1546 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
1547 return -1;
1548 }
1549 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
1550 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
1551 {
1552 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
1553 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
1554 return -1;
1555 }
1556 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
1557 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
1558 {
1559 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
1560 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
1561 return -1;
1562 }
1563 return 0;
1564}
1565
Chilam Ng01120412013-02-19 18:32:21 -08001566int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +05301567{
Chilam Ng01120412013-02-19 18:32:21 -08001568 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1569 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001570 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -07001571 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -08001572
Hoonki Lee27511902013-03-14 18:19:06 -07001573 if (NULL == pHddTdlsCtx)
1574 {
c_hpothu7f63e882013-10-02 19:13:35 +05301575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS not enabled!"));
Hoonki Lee27511902013-03-14 18:19:06 -07001576 return -1;
Chilam Ng01120412013-02-19 18:32:21 -08001577 }
Chilam NG571c65a2013-01-19 12:27:36 +05301578
Hoonki Lee27511902013-03-14 18:19:06 -07001579 if (wlan_hdd_tdls_check_config(config) != 0)
1580 {
1581 return -1;
1582 }
1583
1584 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1585 req_tdls_mode = config->tdls + 1;
1586 if (pHddCtx->tdls_mode == req_tdls_mode)
1587 {
1588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1589 return -1;
1590 }
1591
1592 /* copy the configuration only when given tdls mode is implicit trigger enable */
1593 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1594 {
Chilam Ng01120412013-02-19 18:32:21 -08001595 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1596 }
Chilam NG571c65a2013-01-19 12:27:36 +05301597
Chilam Ng01120412013-02-19 18:32:21 -08001598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1599 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1600 config->tdls,
1601 config->tx_period_t,
1602 config->tx_packet_n,
1603 config->discovery_period_t,
1604 config->discovery_tries_n,
1605 config->idle_timeout_t,
1606 config->idle_packet_n,
1607 config->rssi_hysteresis,
1608 config->rssi_trigger_threshold,
1609 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301610
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001611 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE);
Chilam Ng01120412013-02-19 18:32:21 -08001612
Chilam NG571c65a2013-01-19 12:27:36 +05301613 return 0;
1614}
1615
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001616int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001617{
Hoonki Lee387663d2013-02-05 18:08:43 -08001618 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001619
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001620 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001621 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301622 {
1623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1624 "%s: curr_peer is NULL", __func__);
Chilam NG571c65a2013-01-19 12:27:36 +05301625 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301626 }
Chilam NG571c65a2013-01-19 12:27:36 +05301627
Hoonki Lee387663d2013-02-05 18:08:43 -08001628 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301629
1630 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001631}
1632
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301633int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac,
1634 tANI_BOOLEAN forcePeer)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301635{
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301636 hddTdlsPeer_t *curr_peer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301637 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1638
1639 if ((NULL == pHddCtx)) return -1;
1640
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301641 mutex_lock(&pHddCtx->tdls_lock);
1642
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301643 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
1644 if (curr_peer == NULL)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301645 goto error;
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301646 curr_peer->isForcedPeer = forcePeer;
Naresh Jayaramca7bc3a2014-02-04 23:03:04 +05301647
1648 mutex_unlock(&pHddCtx->tdls_lock);
1649 return 0;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301650error:
1651 mutex_unlock(&pHddCtx->tdls_lock);
1652 return -1;
1653}
1654
Hoonki Lee387663d2013-02-05 18:08:43 -08001655/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1656 otherwise, it returns NULL
1657*/
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301658hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac,
1659 tANI_BOOLEAN mutexLock)
Kiran V1ccee932012-12-12 14:49:46 -08001660{
Hoonki Lee387663d2013-02-05 18:08:43 -08001661 u8 key;
1662 struct list_head *pos;
1663 struct list_head *head;
1664 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001665 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301666 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee387663d2013-02-05 18:08:43 -08001667
c_hpothu7f63e882013-10-02 19:13:35 +05301668 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1669 {
1670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1671 FL("pHddCtx is not valid"));
1672 return 0;
1673 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001674
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301675 if ( mutexLock )
Hoonki Lee387663d2013-02-05 18:08:43 -08001676 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301677 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001678 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001679 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001680 if (NULL == pHddTdlsCtx)
1681 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301682 if ( mutexLock )
1683 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001684 return NULL;
1685 }
1686
1687 key = wlan_hdd_tdls_hash_key(mac);
1688
1689 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001690
1691 list_for_each(pos, head) {
1692 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1693 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1695 "findTdlsPeer: found staId %d", curr_peer->staId);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301696 if ( mutexLock )
1697 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001698 return curr_peer;
1699 }
1700 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301701 if ( mutexLock )
1702 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001703 return NULL;
1704}
1705
Hoonki Leea6d49be2013-04-05 09:43:25 -07001706hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac)
1707{
1708 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1709 hdd_adapter_t *pAdapter = NULL;
1710 tdlsCtx_t *pHddTdlsCtx = NULL;
1711 hddTdlsPeer_t *curr_peer= NULL;
1712 VOS_STATUS status = 0;
1713
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301714 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001715 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1716 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1717 {
1718 pAdapter = pAdapterNode->pAdapter;
1719
1720 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1721 if (NULL != pHddTdlsCtx)
1722 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301723 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001724 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301725 {
1726 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001727 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301728 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07001729 }
1730 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1731 pAdapterNode = pNext;
1732 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301733 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001734 return curr_peer;
1735}
1736
1737
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001738int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001739{
Chilam Ng01120412013-02-19 18:32:21 -08001740 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301741 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001742
Chilam Ng01120412013-02-19 18:32:21 -08001743 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1744
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001745 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001746 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301747 {
1748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1749 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001750 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301751 }
Chilam NG571c65a2013-01-19 12:27:36 +05301752
Atul Mittal115287b2014-07-08 13:26:33 +05301753 wlan_hdd_tdls_set_peer_link_status(curr_peer,
1754 eTDLS_LINK_IDLE,
1755 eTDLS_LINK_UNSPECIFIED);
Hoonki Leecdd8e962013-01-20 00:45:46 -08001756 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001757
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301758 /* Throughput Monitor shall disable the split scan when
1759 * TDLS scan coexistance is disabled.At this point of time
1760 * since TDLS scan coexistance is not meeting the criteria
1761 * to be operational, explicitly make it false to enable
1762 * throughput monitor takes the control of split scan.
1763 */
1764 if (pHddCtx->isTdlsScanCoexistence == TRUE)
1765 {
1766 pHddCtx->isTdlsScanCoexistence = FALSE;
1767 }
1768
Chilam Ng01120412013-02-19 18:32:21 -08001769 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001770 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001771 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001772 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001773}
1774
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001775/* Caller has to take the lock before calling this function */
Hoonki Lee27511902013-03-14 18:19:06 -07001776static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1777{
1778 int i;
1779 struct list_head *head;
1780 hddTdlsPeer_t *tmp;
1781 struct list_head *pos, *q;
1782
Hoonki Lee27511902013-03-14 18:19:06 -07001783 for (i = 0; i < 256; i++) {
1784 head = &pHddTdlsCtx->peer_list[i];
1785 list_for_each_safe (pos, q, head) {
1786 tmp = list_entry(pos, hddTdlsPeer_t, node);
1787 tmp->tx_pkt = 0;
1788 tmp->rx_pkt = 0;
1789 }
1790 }
Hoonki Lee27511902013-03-14 18:19:06 -07001791
1792 return ;
1793}
1794
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001795/* Caller has to take the lock before calling this function */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001796static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001797{
1798 int i;
1799 struct list_head *head;
1800 hddTdlsPeer_t *tmp;
1801 struct list_head *pos, *q;
1802
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001803 pHddTdlsCtx->discovery_peer_cnt = 0;
1804
1805 for (i = 0; i < 256; i++) {
1806 head = &pHddTdlsCtx->peer_list[i];
1807 list_for_each_safe (pos, q, head) {
1808 tmp = list_entry(pos, hddTdlsPeer_t, node);
1809 tmp->discovery_processed = 0;
1810 }
1811 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001812
1813 return 0;
1814}
1815
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001816static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001817{
1818 int i;
1819 struct list_head *head;
1820 struct list_head *pos, *q;
1821 int discovery_peer_cnt=0;
1822 hddTdlsPeer_t *tmp;
1823
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001824 /*
1825 * This function expects the callers to acquire the Mutex.
1826 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001827
1828 for (i = 0; i < 256; i++) {
1829 head = &pHddTdlsCtx->peer_list[i];
1830 list_for_each_safe (pos, q, head) {
1831 tmp = list_entry(pos, hddTdlsPeer_t, node);
1832 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001833 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1834 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001835 discovery_peer_cnt++;
1836 }
1837 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001838 return discovery_peer_cnt;
1839}
1840
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001841tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001842{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001843 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1844
c_hpothu7f63e882013-10-02 19:13:35 +05301845 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1846 {
1847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1848 FL("pHddCtx is not valid"));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001849 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05301850 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08001851
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001852 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001853}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001854
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301855hddTdlsPeer_t *wlan_hdd_tdls_get_first_connected_peer(hdd_adapter_t *pAdapter)
1856{
1857 int i;
1858 struct list_head *head;
1859 struct list_head *pos;
1860 hddTdlsPeer_t *curr_peer = NULL;
1861 tdlsCtx_t *pHddTdlsCtx;
1862 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1863
1864 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1865 {
1866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1867 FL("pHddCtx is not valid"));
1868 return NULL;
1869 }
1870
1871 mutex_lock(&pHddCtx->tdls_lock);
1872 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1873 if (NULL == pHddTdlsCtx) {
1874 mutex_unlock(&pHddCtx->tdls_lock);
1875 return NULL;
1876 }
1877 for (i = 0; i < 256; i++) {
1878 head = &pHddTdlsCtx->peer_list[i];
1879
1880 list_for_each(pos, head) {
1881 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05301882 if (curr_peer && (curr_peer->link_status == eTDLS_LINK_CONNECTED))
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301883 {
1884 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05301885 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1886 "%s: " MAC_ADDRESS_STR " eTDLS_LINK_CONNECTED",
1887 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301888 return curr_peer;
1889 }
1890 }
1891 }
1892 mutex_unlock(&pHddCtx->tdls_lock);
1893 return NULL;
1894}
1895
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001896int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001897{
1898 int i;
1899 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001900 struct list_head *head;
1901 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001902 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001903 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301904 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1905
c_hpothu7f63e882013-10-02 19:13:35 +05301906 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1907 {
1908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1909 FL("pHddCtx is not valid"));
1910 return 0;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301911 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001912
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001913 init_len = buflen;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001914 len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n",
1915 "MAC", "Id", "cap", "up", "RSSI");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001916 buf += len;
1917 buflen -= len;
1918 /* 1234567890123456789012345678901234567 */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001919 len = scnprintf(buf, buflen, "---------------------------------\n");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001920 buf += len;
1921 buflen -= len;
1922
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301923 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001924 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001925 if (NULL == pHddTdlsCtx) {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301926 mutex_unlock(&pHddCtx->tdls_lock);
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001927 len = scnprintf(buf, buflen, "TDLS not enabled\n");
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001928 return len;
1929 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001930 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001931 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001932
Hoonki Lee387663d2013-02-05 18:08:43 -08001933 list_for_each(pos, head) {
1934 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001935
Hoonki Lee387663d2013-02-05 18:08:43 -08001936 if (buflen < 32+1)
1937 break;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001938 len = scnprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001939 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1940 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001941 curr_peer->staId,
1942 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001943 TDLS_IS_CONNECTED(curr_peer) ? "Y":"N",
Hoonki Lee387663d2013-02-05 18:08:43 -08001944 curr_peer->rssi);
1945 buf += len;
1946 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001947 }
1948 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301949 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001950 return init_len-buflen;
1951}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001952
1953void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1954{
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05301955 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301956 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001957
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05301958 if ((NULL == pHddCtx))
c_hpothu7f63e882013-10-02 19:13:35 +05301959 {
Agarwal Ashishbf98caf2014-03-25 13:29:11 +05301960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1961 FL("pHddCtx or pHddTdlsCtx points to NULL"));
c_hpothu7f63e882013-10-02 19:13:35 +05301962 return;
1963 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301964
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301965 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001966
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05301967 if (0 != wlan_hdd_sta_tdls_init(pAdapter))
1968 {
1969 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wlan_hdd_sta_tdls_init failed",__func__);
1970 mutex_unlock(&pHddCtx->tdls_lock);
1971 return;
1972 }
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05301973
1974 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1975 if ((NULL == pHddTdlsCtx))
1976 {
1977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1978 FL("pHddCtx or pHddTdlsCtx points to NULL device mode = %d"), pAdapter->device_mode);
1979 mutex_unlock(&pHddCtx->tdls_lock);
1980 return;
1981 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001982 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1983 "%s, update %d discover %d", __func__,
1984 pHddTdlsCtx->threshold_config.tx_period_t,
1985 pHddTdlsCtx->threshold_config.discovery_period_t);
1986
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001987 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1988 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001989 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001990 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001991 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001992
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001993#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001994 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1995 &pHddTdlsCtx->peerDiscoverTimer,
1996 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001997#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001998 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1999 &pHddTdlsCtx->peerUpdateTimer,
2000 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08002001 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302002 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08002003
2004}
2005
2006void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
2007{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002008 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302009 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2010
Deepthi Gowribfd17132014-11-14 17:59:04 +05302011 if (NULL == pHddCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302012 {
2013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Deepthi Gowribfd17132014-11-14 17:59:04 +05302014 FL(" pHddCtx points to NULL"));
c_hpothu7f63e882013-10-02 19:13:35 +05302015 return;
2016 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08002017
2018 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
2019
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302020 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08002021 if (NULL == pHddTdlsCtx)
2022 {
c_hpothu7f63e882013-10-02 19:13:35 +05302023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2024 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302025 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08002026 return;
2027 }
Masti, Narayanraddide96b992015-01-08 13:00:58 +05302028
2029#ifdef WLAN_OPEN_SOURCE
2030 cancel_work_sync(&pHddTdlsCtx->implicit_setup);
2031#endif
2032
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002033 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002034 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08002035
Mahesh A Saptasagarf5b8eff2015-01-31 01:07:07 +05302036 wlan_hdd_tdls_exit(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08002037
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302038 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08002039}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002040
2041void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
2042{
2043 pAdapter->mgmtTxCompletionStatus = statusCode;
2044 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
2045 __func__, statusCode);
2046 complete(&pAdapter->tdls_mgmt_comp);
2047}
2048
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002049void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002050{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002051 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002052
c_hpothu7f63e882013-10-02 19:13:35 +05302053 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2054 {
2055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2056 FL("pHddCtx is not valid"));
2057 return;
2058 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002059
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302060 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302061
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002062 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002063 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002064
2065 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
2066 __func__, pHddCtx->connected_peer_count);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302067
2068 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002069}
2070
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002071void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002072{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002073 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002074
c_hpothu7f63e882013-10-02 19:13:35 +05302075 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2076 {
2077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2078 FL("pHddCtx is not valid"));
2079 return;
2080 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002081
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302082 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302083
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002084 if (pHddCtx->connected_peer_count)
2085 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002086 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002087
2088 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
2089 __func__, pHddCtx->connected_peer_count);
2090
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302091 mutex_unlock(&pHddCtx->tdls_lock);
2092
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002093}
2094
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002095void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002096{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002097 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002098 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee14621352013-04-16 17:51:19 -07002099 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002100
c_hpothu7f63e882013-10-02 19:13:35 +05302101 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
2102 {
Sushant Kaushik125ae692014-11-25 17:38:48 +05302103 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
c_hpothu7f63e882013-10-02 19:13:35 +05302104 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
2105 return;
2106 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08002107
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302108 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Lee14621352013-04-16 17:51:19 -07002109 if (NULL != curr_peer)
2110 {
2111 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2112 "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR,
2113 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac));
2114 return;
2115 }
2116
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002117 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
2118 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002119 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002120 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002121 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
2122 {
2123 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002124 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
2125 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002126 hdd_enable_bmps_imps(pHddCtx);
2127 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002128 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002129 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002130 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002131 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
2132 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002133 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2134 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002135 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
2136 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002137 }
2138 return;
2139}
2140
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002141u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
2142{
2143 hddTdlsPeer_t *curr_peer;
2144
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302145 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002146 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05302147 {
2148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2149 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002150 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05302151 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002152
2153 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
2154}
2155
Hoonki Leefb8df672013-04-10 18:20:34 -07002156/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL.
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002157 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
2158 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
2159 mac is NULL, this argument is ignored, and check for all the peer list.
2160 */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302161static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002162{
2163 int i;
2164 struct list_head *head;
2165 hddTdlsPeer_t *curr_peer;
2166 struct list_head *pos;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302167 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302168
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302169 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302170 {
2171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2172 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302173 return NULL;
c_hpothu7f63e882013-10-02 19:13:35 +05302174 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302175
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002176 for (i = 0; i < 256; i++) {
2177 head = &pHddTdlsCtx->peer_list[i];
2178 list_for_each(pos, head) {
2179 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
2180 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
2181 continue;
2182 }
2183 else
2184 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08002185 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002186 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002187 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002188 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07002189 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Hoonki Leefb8df672013-04-10 18:20:34 -07002190 return curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002191 }
2192 }
2193 }
2194 }
Hoonki Leefb8df672013-04-10 18:20:34 -07002195 return NULL;
2196}
2197
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302198hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8 *mac, u8 skip_self)
Hoonki Leefb8df672013-04-10 18:20:34 -07002199{
2200 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2201 hdd_adapter_t *pAdapter = NULL;
2202 tdlsCtx_t *pHddTdlsCtx = NULL;
2203 hddTdlsPeer_t *curr_peer= NULL;
2204 VOS_STATUS status = 0;
2205
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302206 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302207
Hoonki Leefb8df672013-04-10 18:20:34 -07002208 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2209 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2210 {
2211 pAdapter = pAdapterNode->pAdapter;
2212
2213 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2214 if (NULL != pHddTdlsCtx)
2215 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302216 curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self);
Hoonki Leefb8df672013-04-10 18:20:34 -07002217 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302218 {
2219 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07002220 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302221 }
Hoonki Leefb8df672013-04-10 18:20:34 -07002222 }
2223 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2224 pAdapterNode = pNext;
2225 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302226 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07002227 return NULL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08002228}
Hoonki Lee27511902013-03-14 18:19:06 -07002229
2230static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
2231{
Hoonki Lee27511902013-03-14 18:19:06 -07002232 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07002233}
2234
2235static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
2236{
2237 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002238 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07002239 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002240 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002241
Hoonki Lee27511902013-03-14 18:19:06 -07002242
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002243#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002244 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
2245 &pHddTdlsCtx->peerDiscoverTimer,
2246 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002247#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002248 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
2249 &pHddTdlsCtx->peerUpdateTimer,
2250 pHddTdlsCtx->threshold_config.tx_period_t);
Hoonki Lee27511902013-03-14 18:19:06 -07002251}
2252
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002253void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
2254 eTDLSSupportMode tdls_mode,
2255 v_BOOL_t bUpdateLast)
Hoonki Lee27511902013-03-14 18:19:06 -07002256{
2257 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2258 VOS_STATUS status;
2259 hdd_adapter_t *pAdapter;
2260 tdlsCtx_t *pHddTdlsCtx;
2261
2262 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
c_hpothu7f63e882013-10-02 19:13:35 +05302263
2264 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2265 {
2266 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2267 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302268 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302269 }
Hoonki Lee27511902013-03-14 18:19:06 -07002270
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302271 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07002272
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002273 if (pHddCtx->tdls_mode == tdls_mode)
2274 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002275 hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302276 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002277 return;
2278 }
2279
Hoonki Lee27511902013-03-14 18:19:06 -07002280 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2281
2282 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2283 {
2284 pAdapter = pAdapterNode->pAdapter;
Hoonki Leea6d49be2013-04-05 09:43:25 -07002285 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2286 if (NULL != pHddTdlsCtx)
Hoonki Lee27511902013-03-14 18:19:06 -07002287 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002288 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
2289 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
2290 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
2291 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
2292 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07002293 }
2294 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2295 pAdapterNode = pNext;
2296 }
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002297 if(bUpdateLast)
2298 {
2299 pHddCtx->tdls_mode_last = tdls_mode;
2300 }
2301 else
2302 {
2303 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
2304 }
Hoonki Lee27511902013-03-14 18:19:06 -07002305 pHddCtx->tdls_mode = tdls_mode;
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002306
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302307 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -07002308}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002309
Mahesh A Saptasagar8b231b32014-08-11 11:58:15 +05302310static void __wlan_hdd_tdls_pre_setup(struct work_struct *work)
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002311{
Hoonki Leed37cbb32013-04-20 00:31:14 -07002312 tdlsCtx_t *pHddTdlsCtx =
2313 container_of(work, tdlsCtx_t, implicit_setup);
2314 hdd_context_t *pHddCtx;
2315 hddTdlsPeer_t *curr_peer;
Hoonki Leefb8df672013-04-10 18:20:34 -07002316 hddTdlsPeer_t *temp_peer;
Hoonki Leed37cbb32013-04-20 00:31:14 -07002317 int status;
2318
2319 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302320 {
2321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2322 FL("pHddTdlsCtx is NULL"));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002323 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302324 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002325
2326 if (unlikely(TDLS_CTX_MAGIC != pHddTdlsCtx->magic))
c_hpothu7f63e882013-10-02 19:13:35 +05302327 {
2328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2329 "%s: tdls magic no missmatch %u", __func__, pHddTdlsCtx->magic);
Hoonki Leed37cbb32013-04-20 00:31:14 -07002330 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302331 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002332
2333 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
Hoonki Leefb8df672013-04-10 18:20:34 -07002334
c_hpothu7f63e882013-10-02 19:13:35 +05302335 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2336 {
2337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2338 FL("pHddCtx is not valid"));
Hoonki Leefb8df672013-04-10 18:20:34 -07002339 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302340 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002341
Hoonki Leed37cbb32013-04-20 00:31:14 -07002342 curr_peer = pHddTdlsCtx->curr_candidate;
2343
2344 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302345 {
2346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2347 FL("curr_peer is NULL"));
2348
Hoonki Leed37cbb32013-04-20 00:31:14 -07002349 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302350 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002351
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002352 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
2353 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002354 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002355 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
2356 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002357
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302358 temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002359 if (NULL != temp_peer)
2360 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002361 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored",
Hoonki Leefb8df672013-04-10 18:20:34 -07002362 __func__, MAC_ADDR_ARRAY(temp_peer->peerMac));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002363 goto done;
Hoonki Leefb8df672013-04-10 18:20:34 -07002364 }
2365
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002366 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
Atul Mittal115287b2014-07-08 13:26:33 +05302367 wlan_hdd_tdls_set_peer_link_status(curr_peer,
2368 eTDLS_LINK_DISCOVERING,
2369 eTDLS_LINK_SUCCESS);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002370
Hoonki Leed37cbb32013-04-20 00:31:14 -07002371 status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy,
2372 pHddTdlsCtx->pAdapter->dev,
2373 curr_peer->peerMac);
2374
2375 if (0 != status)
2376 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002377 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " discovery could not sent",
Hoonki Leed37cbb32013-04-20 00:31:14 -07002378 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
2379 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
Atul Mittal115287b2014-07-08 13:26:33 +05302380 wlan_hdd_tdls_set_peer_link_status(curr_peer,
2381 eTDLS_LINK_IDLE,
2382 eTDLS_LINK_UNSPECIFIED);
Hoonki Leed37cbb32013-04-20 00:31:14 -07002383 goto done;
2384 }
2385
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002386 pHddTdlsCtx->discovery_sent_cnt++;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302387
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302388 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302389
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002390 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302391
Pradeep Reddy POTTETI219ced32014-11-14 16:33:57 +05302392 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
2393 &pHddTdlsCtx->peerDiscoveryTimeoutTimer,
2394 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
2395
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302396 mutex_unlock(&pHddCtx->tdls_lock);
Jeff Johnson0299d0a2013-10-30 12:37:43 -07002397 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %u timeout %u msec",
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002398 __func__, pHddTdlsCtx->discovery_sent_cnt,
2399 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002400
Hoonki Leed37cbb32013-04-20 00:31:14 -07002401done:
2402 pHddTdlsCtx->curr_candidate = NULL;
2403 pHddTdlsCtx->magic = 0;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002404 return;
2405}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002406
Mahesh A Saptasagar8b231b32014-08-11 11:58:15 +05302407
2408static void wlan_hdd_tdls_pre_setup(struct work_struct *work)
2409{
2410 vos_ssr_protect(__func__);
2411 __wlan_hdd_tdls_pre_setup(work);
2412 vos_ssr_unprotect(__func__);
2413
2414 return;
2415}
2416
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002417tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
2418{
2419 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2420 hdd_adapter_t *pAdapter = NULL;
2421 tdlsCtx_t *pHddTdlsCtx = NULL;
2422 VOS_STATUS status = 0;
2423 tANI_U32 count = 0;
2424
2425 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2426 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2427 {
2428 pAdapter = pAdapterNode->pAdapter;
2429
Hoonki Leea6d49be2013-04-05 09:43:25 -07002430 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2431 if (NULL != pHddTdlsCtx)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002432 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002433 count = count + pHddTdlsCtx->discovery_sent_cnt;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002434 }
2435 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2436 pAdapterNode = pNext;
2437 }
2438 return count;
2439}
2440
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002441void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002442{
2443 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2444 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2445
2446 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
c_hpothu7f63e882013-10-02 19:13:35 +05302447 {
2448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2449 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002450 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302451 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002452
2453 if ((0 == pHddCtx->connected_peer_count) &&
2454 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
2455 {
2456 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
2457 return;
2458 }
2459 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
2460 return;
2461}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002462
2463void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
2464{
2465 if (NULL == tdls_scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +05302466 {
2467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2468 FL("tdls_scan_ctx is NULL"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002469 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302470 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002471
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002472 tdls_scan_ctx->attempt = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -07002473 tdls_scan_ctx->reject = 0;
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002474 tdls_scan_ctx->magic = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002475 tdls_scan_ctx->scan_request = NULL;
2476 return;
2477}
2478
2479int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
2480 struct wiphy *wiphy,
2481#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2482 struct net_device *dev,
2483#endif
2484 struct cfg80211_scan_request *request)
2485{
2486 tdls_scan_context_t *scan_ctx;
2487
c_hpothu7f63e882013-10-02 19:13:35 +05302488 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2489 {
2490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2491 FL("pHddCtx is not valid"));
2492 return 0;
2493 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002494
2495 scan_ctx = &pHddCtx->tdls_scan_ctxt;
2496
2497 scan_ctx->wiphy = wiphy;
2498#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2499 scan_ctx->dev = dev;
2500#endif
2501
2502 scan_ctx->scan_request = request;
2503 return 0;
2504}
2505
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002506static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
2507 struct wiphy *wiphy,
2508#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2509 struct net_device *dev,
2510#endif
2511 struct cfg80211_scan_request *request,
2512 unsigned long delay)
2513{
2514 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
2515 {
2516#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2517 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
2518#else
2519 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
2520#endif
2521 pHddCtx->tdls_scan_ctxt.attempt = 0;
2522 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
2523 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002524 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
2525}
2526
2527/* return negative = caller should stop and return error code immediately
2528 return 0 = caller should stop and return success immediately
2529 return 1 = caller can continue to scan
2530 */
2531int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
2532 struct wiphy *wiphy,
2533#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2534 struct net_device *dev,
2535#endif
2536 struct cfg80211_scan_request *request)
2537{
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002538 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2539 u16 connectedTdlsPeers;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302540 hddTdlsPeer_t *curr_peer, *connected_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002541 unsigned long delay;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302542 hdd_config_t *cfg_param = pHddCtx->cfg_ini;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002543
c_hpothu7f63e882013-10-02 19:13:35 +05302544 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2545 {
2546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2547 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002548 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05302549 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002550
2551 /* if tdls is not enabled, then continue scan */
Pradeep Reddy POTTETIf0569d72014-12-13 16:54:03 +05302552 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
2553 (pHddCtx->is_tdls_btc_enabled == FALSE))
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002554 return 1;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302555 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002556 if (NULL != curr_peer)
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002557 {
Hoonki Leefb8df672013-04-10 18:20:34 -07002558 if (pHddCtx->tdls_scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT)
2559 {
2560 pHddCtx->tdls_scan_ctxt.reject = 0;
2561 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2562 "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle",
2563 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->tdls_scan_ctxt.reject);
2564
Atul Mittal115287b2014-07-08 13:26:33 +05302565 wlan_hdd_tdls_set_peer_link_status (curr_peer,
2566 eTDLS_LINK_IDLE,
2567 eTDLS_LINK_UNSPECIFIED);
Hoonki Leefb8df672013-04-10 18:20:34 -07002568 return 1;
2569 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002570 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Leefb8df672013-04-10 18:20:34 -07002571 "%s: tdls in progress. scan rejected %d",
2572 __func__, pHddCtx->tdls_scan_ctxt.reject);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002573 return -EBUSY;
2574 }
2575
2576 /* tdls teardown is ongoing */
2577 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
2578 {
2579 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2580 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
2581 {
2582 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2583 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2584 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
2585 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
2586
2587 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2588#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2589 dev,
2590#endif
2591 request,
2592 msecs_to_jiffies(delay));
2593 /* scan should not continue */
2594 return 0;
2595 }
2596 /* no connected peer or max retry reached, scan continue */
2597 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2598 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
2599 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
2600 return 1;
2601 }
Agarwal Ashishef54a182014-12-16 15:07:31 +05302602
2603 /* if fEnableTDLSScan flag is 1 ; driverwill allow scan even if
2604 * peer station is not buffer STA capable
2605 *
2606 * RX: If there is any RX activity, device will lose RX packets,
2607 * as peer will not be aware that device is off channel.
2608 * TX: TX is stopped whenever device initiate scan.
2609 */
2610 if (pHddCtx->cfg_ini->fEnableTDLSScan == 1)
2611 {
2612 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2613 FL("Allow SCAN in all TDLS cases"));
2614 return 1;
2615 }
2616
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002617 /* while tdls is up, first time scan */
2618 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
2619 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
2620 {
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002621 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302622
2623 /* check the TDLS link and Scan coexistance Capability */
2624 if ( (TRUE == pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport) &&
2625 (TRUE == sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE)) &&
2626 (connectedTdlsPeers == 1) )
2627 {
2628 /* get connected peer information */
2629 connected_peer = wlan_hdd_tdls_get_first_connected_peer(pAdapter);
2630 if (NULL == connected_peer) {
2631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2632 "%s: Invalid connected_peer, Continue Scanning", __func__);
2633 /* scan should continue */
2634 return 1;
2635 }
2636 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2637 ("%s: TDLS Scan Co-exist supported connectedTdlsPeers =%d buffersta =%d"),
2638 __func__,connectedTdlsPeers,connected_peer->isBufSta);
2639
2640 if (connected_peer->isBufSta)
2641 {
2642 pHddCtx->isTdlsScanCoexistence = TRUE;
2643 if ((cfg_param->dynSplitscan) && (!pHddCtx->issplitscan_enabled))
2644 {
2645 pHddCtx->issplitscan_enabled = TRUE;
2646 sme_enable_disable_split_scan(
2647 WLAN_HDD_GET_HAL_CTX(pAdapter),
2648 cfg_param->nNumStaChanCombinedConc,
2649 cfg_param->nNumP2PChanCombinedConc);
2650 }
2651 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2652 ("%s:%d TDLS Scan Co-exist supported splitscan_enabled =%d "),
2653 __func__, __LINE__, pHddCtx->issplitscan_enabled);
2654 return 1;
2655 }
2656
2657 }
2658 else
2659 {
2660 /* Throughput Monitor shall disable the split scan when
2661 * TDLS scan coexistance is disabled.At this point of time
2662 * since TDLS scan coexistance is not meeting the criteria
2663 * to be operational, explicitly make it false to enable
2664 * throughput monitor takes the control of split scan.
2665 */
2666 pHddCtx->isTdlsScanCoexistence = FALSE;
2667 }
2668 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2669 ("%s: TDLS Scan Co-exist not supported connectedTdlsPeers =%d"
2670 " TDLSScanCoexSupport param =%d TDLS_SCAN_COEXISTENCE =%d"),
2671 __func__, connectedTdlsPeers,
2672 pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport,
2673 sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE));
2674
Atul Mittal5803b342014-09-04 15:31:19 +05302675 /* disable implicit trigger logic & tdls operatoin */
2676 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302677 /* fall back to the implementation of teardown the peers on the scan
2678 * when the number of connected peers are more than one. TDLS Scan
2679 * coexistance feature is exercised only when a single peer is
2680 * connected and the DUT shall not advertize the Buffer Sta capability,
2681 * so that the peer shall not go to the TDLS power save
2682 */
2683
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002684 if (connectedTdlsPeers)
2685 {
2686 tANI_U8 staIdx;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002687 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002688
2689 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
2690 {
2691 if (pHddCtx->tdlsConnInfo[staIdx].staId)
2692 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002693 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002694 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
2695
2696#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leea6d49be2013-04-05 09:43:25 -07002697 curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
2698 if(curr_peer)
2699 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002700#endif
2701 }
2702 }
2703 /* schedule scan */
2704 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2705
2706 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2707 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
2708 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
2709 delay);
2710
2711 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2712#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2713 dev,
2714#endif
2715 request,
2716 msecs_to_jiffies(delay));
2717 /* scan should not continue */
2718 return 0;
2719 }
2720 /* no connected peer, scan continue */
2721 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2722 "%s: tdls_mode %d, and no tdls connection. scan allowed",
2723 __func__, pHddCtx->tdls_mode);
2724 }
2725 return 1;
2726}
2727
2728void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
2729{
2730 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002731
c_hpothu7f63e882013-10-02 19:13:35 +05302732 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2733 {
2734 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2735 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002736 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302737 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002738
Pradeep Reddy POTTETIf0569d72014-12-13 16:54:03 +05302739 if (pHddCtx->is_tdls_btc_enabled == FALSE)
2740 return;
Sunil Dutt41de4e22013-11-14 18:09:02 +05302741
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002742 /* free allocated memory at scan time */
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002743 wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002744
2745 /* if tdls was enabled before scan, re-enable tdls mode */
2746 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
2747 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
2748 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002749 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002750 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
2751
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002752 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002753 }
2754 wlan_hdd_tdls_check_bmps(pAdapter);
2755}
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002756
2757void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
2758 vos_timer_t *timer,
2759 v_U32_t expirationTime)
2760{
2761 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2762
2763 if (NULL == pHddStaCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302764 {
2765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2766 FL("pHddStaCtx is NULL"));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002767 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302768 }
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002769
2770 /* Check whether driver load unload is in progress */
2771 if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
2772 {
2773 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2774 "%s: Driver load/unload is in progress.", __func__);
2775 return;
2776 }
2777
2778 if (hdd_connIsConnected(pHddStaCtx))
2779 {
2780 vos_timer_stop(timer);
2781 vos_timer_start(timer, expirationTime);
2782 }
2783}
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002784void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
2785 hddTdlsPeer_t *curr_peer,
2786 tANI_U16 reason)
2787{
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302788 hdd_context_t *pHddCtx;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302789
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002790 if (NULL == pAdapter || NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302791 {
2792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2793 FL("parameters passed are invalid"));
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002794 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302795 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002796
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302797 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2798
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002799 if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
2800 return;
2801
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302802 /* Throughput Monitor shall disable the split scan when
2803 * TDLS scan coexistance is disabled.At this point of time
2804 * since TDLS scan coexistance is not meeting the criteria
2805 * to be operational, explicitly make it false to enable
2806 * throughput monitor takes the control of split scan.
2807 */
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302808 if (pHddCtx && (pHddCtx->isTdlsScanCoexistence == TRUE))
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302809 {
2810 pHddCtx->isTdlsScanCoexistence = FALSE;
2811 }
2812
Atul Mittal115287b2014-07-08 13:26:33 +05302813 wlan_hdd_tdls_set_peer_link_status(curr_peer,
2814 eTDLS_LINK_TEARING,
Atul Mittal271a7652014-09-12 13:18:22 +05302815 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002816 cfg80211_tdls_oper_request(pAdapter->dev,
2817 curr_peer->peerMac,
2818 NL80211_TDLS_TEARDOWN,
2819 reason,
2820 GFP_KERNEL);
2821}
Atul Mittal115287b2014-07-08 13:26:33 +05302822
2823
2824/*EXT TDLS*/
2825int wlan_hdd_set_callback(hddTdlsPeer_t *curr_peer,
2826 cfg80211_exttdls_callback callback)
2827{
2828
2829 hdd_context_t *pHddCtx;
2830 hdd_adapter_t *pAdapter;
2831
2832 if (!curr_peer) return -1;
2833
2834 pAdapter = curr_peer->pHddTdlsCtx->pAdapter;
2835 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2836 if ((NULL == pHddCtx)) return -1;
2837
2838 mutex_lock(&pHddCtx->tdls_lock);
2839
2840 curr_peer->state_change_notification = callback;
2841
2842 mutex_unlock(&pHddCtx->tdls_lock);
2843 return 0;
2844
2845
2846}
2847
2848void wlan_hdd_tdls_get_wifi_hal_state(hddTdlsPeer_t *curr_peer,
2849 tANI_S32 *state,
2850 tANI_S32 *reason)
2851{
2852 *reason = curr_peer->reason;
2853
2854 switch(curr_peer->link_status)
2855 {
2856 case eTDLS_LINK_IDLE:
Atul Mittal115287b2014-07-08 13:26:33 +05302857 case eTDLS_LINK_DISCOVERED:
2858 *state = WIFI_TDLS_ENABLED;
2859 break;
Atul Mittalad630e42014-10-07 19:19:14 +05302860 case eTDLS_LINK_DISCOVERING:
Atul Mittal115287b2014-07-08 13:26:33 +05302861 case eTDLS_LINK_CONNECTING:
2862 *state = WIFI_TDLS_TRYING;
2863 break;
2864 case eTDLS_LINK_CONNECTED:
2865 *state = WIFI_TDLS_ESTABLISHED;
2866 break;
2867 case eTDLS_LINK_TEARING:
2868 *state = WIFI_TDLS_DROPPED;
2869 break;
2870 }
2871
2872}
2873
2874int wlan_hdd_tdls_get_status(hdd_adapter_t *pAdapter,
2875 tANI_U8* mac,
2876 tANI_S32 *state,
2877 tANI_S32 *reason)
2878{
2879
2880 hddTdlsPeer_t *curr_peer;
Atul Mittala75fced2014-10-06 13:59:07 +05302881 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05302882 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
2883 if (curr_peer == NULL)
2884 {
Atul Mittala75fced2014-10-06 13:59:07 +05302885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Atul Mittal115287b2014-07-08 13:26:33 +05302886 FL("curr_peer is NULL"));
Atul Mittal115287b2014-07-08 13:26:33 +05302887
Atul Mittala75fced2014-10-06 13:59:07 +05302888 *state = WIFI_TDLS_DISABLED;
2889 *reason = eTDLS_LINK_UNSPECIFIED;
2890 }
2891 else
2892 {
2893 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
2894 (FALSE == curr_peer->isForcedPeer))
2895 {
2896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2897 FL("curr_peer is not Forced"));
2898 *state = WIFI_TDLS_DISABLED;
2899 *reason = eTDLS_LINK_UNSPECIFIED;
2900 }
2901 else
2902 {
2903 wlan_hdd_tdls_get_wifi_hal_state(curr_peer, state, reason);
2904 }
2905 }
Atul Mittal115287b2014-07-08 13:26:33 +05302906 return (0);
2907}
2908
Agarwal Ashishef54a182014-12-16 15:07:31 +05302909int hdd_set_tdls_scan_type(hdd_adapter_t *pAdapter,
2910 tANI_U8 *ptr)
2911{
2912 int tdls_scan_type;
Hema Aparna Medicharla26b98042015-01-21 15:02:01 +05302913 hdd_context_t *pHddCtx;
Agarwal Ashishef54a182014-12-16 15:07:31 +05302914 if (NULL == pAdapter)
2915 {
2916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2917 "%s: pAdapter is NULL", __func__);
2918 return -EINVAL;
2919 }
Hema Aparna Medicharla26b98042015-01-21 15:02:01 +05302920 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Agarwal Ashishef54a182014-12-16 15:07:31 +05302921 tdls_scan_type = ptr[9] - '0';
2922
2923 if (tdls_scan_type <= 2)
2924 {
2925 pHddCtx->cfg_ini->fEnableTDLSScan = tdls_scan_type;
2926 return 0;
2927 }
2928 else
2929 {
2930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2931 " Wrong value is given for tdls_scan_type "
2932 " Making fEnableTDLSScan as 0 ");
2933 pHddCtx->cfg_ini->fEnableTDLSScan = 0;
2934 return -EINVAL;
2935 }
2936}
2937
Atul Mittal115287b2014-07-08 13:26:33 +05302938/*EXT TDLS*/
2939