blob: e228607870e074598f1074d8e29d7803ccf19bb6 [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Kiet Lam842dad02014-02-18 18:44:02 -08002 * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved.
3 *
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"
Kiran V1ccee932012-12-12 14:49:46 -080046
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
152 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
153
c_hpothu7f63e882013-10-02 19:13:35 +0530154 if(0 != (wlan_hdd_validate_context(pHddCtx)))
155 {
156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
157 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530158 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530159 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530160
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530161 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800162
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800163 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800164
Hoonki Lee387663d2013-02-05 18:08:43 -0800165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
166
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800167 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800168 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800169
Chilam NG571c65a2013-01-19 12:27:36 +0530170 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800171 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530172
Hoonki Lee387663d2013-02-05 18:08:43 -0800173 list_for_each (pos, head) {
174 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530175
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800176 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800177 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
178 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800179 curr_peer->discovery_processed,
180 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800181 curr_peer->tdls_support,
182 curr_peer->link_status,
183 curr_peer->discovery_attempt,
184 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800185
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800186 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
187 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530188
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800189 curr_peer->discovery_processed = 1;
190 discover_req_sent++;
191 pHddTdlsCtx->discovery_peer_cnt--;
192
193 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800194 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800195 (curr_peer->tx_pkt >=
196 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800197
198 if (curr_peer->discovery_attempt <
199 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800200 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
201 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800202 curr_peer->peerMac,
203 WLAN_TDLS_DISCOVERY_REQUEST,
Pradeep Reddy POTTETIca171f82014-03-21 14:17:35 +0530204 1, 0, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800205 curr_peer->discovery_attempt++;
206 }
207 else
208 {
209 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
210 "%s: Maximum Discovery retries reached", __func__);
211 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
212 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800213
214 }
215 }
Chilam NG571c65a2013-01-19 12:27:36 +0530216 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800217 else
218 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800219 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800220 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800221exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800222
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800223 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
224 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
225 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
226 pHddTdlsCtx->discovery_peer_cnt);
227 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800228 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800229 goto done;
230 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800231 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
232
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800233 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530234
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530235 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -0700236
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800237 /* Commenting out the following function as it was introducing
238 * a race condition when pHddTdlsCtx is deleted. Also , this
239 * function is consuming more time in the timer callback.
240 * RSSI based trigger needs to revisit this part of the code.
241 */
242
243 /*
244 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
245 */
Chilam NG571c65a2013-01-19 12:27:36 +0530246
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800247done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800248 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800249
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800250 if ( !doMutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530251 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800252 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800253}
Hoonki Leed37cbb32013-04-20 00:31:14 -0700254#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530255
Hoonki Lee387663d2013-02-05 18:08:43 -0800256static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530257{
258 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800259 struct list_head *head;
260 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530261 hddTdlsPeer_t *curr_peer;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530262 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
263 hdd_context_t *pHddCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800264
c_hpothu7f63e882013-10-02 19:13:35 +0530265 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
266 {
267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
268 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530269 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530270 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530271
272 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
273
c_hpothu7f63e882013-10-02 19:13:35 +0530274 if(0 != (wlan_hdd_validate_context(pHddCtx)))
275 {
276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
277 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530278 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530279 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530280
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530281 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800282
Chilam NG571c65a2013-01-19 12:27:36 +0530283 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800284 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530285
Hoonki Lee387663d2013-02-05 18:08:43 -0800286 list_for_each (pos, head) {
287 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530288
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800289 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700290 "%s: " MAC_ADDRESS_STR " link_status %d"
291 " tdls_support %d", __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700292 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800293
Chilam NG571c65a2013-01-19 12:27:36 +0530294 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800295 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700296 "tx %d, rx %d (thr.pkt %d/idle %d), rssi %d (thr.trig %d/hys %d/tear %d)",
297 curr_peer->tx_pkt, curr_peer->rx_pkt,
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800298 pHddTdlsCtx->threshold_config.tx_packet_n,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700299 pHddTdlsCtx->threshold_config.idle_packet_n,
300 curr_peer->rssi,
301 pHddTdlsCtx->threshold_config.rssi_trigger_threshold,
302 pHddTdlsCtx->threshold_config.rssi_hysteresis,
303 pHddTdlsCtx->threshold_config.rssi_teardown_threshold);
Chilam Ng01120412013-02-19 18:32:21 -0800304
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800305 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
306 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530307
308 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
309 (FALSE == curr_peer->isForcedPeer)) {
310 continue;
311 }
312
Chilam NG571c65a2013-01-19 12:27:36 +0530313 if (curr_peer->tx_pkt >=
314 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800315
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800316 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800317 {
318
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700319 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530320#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leed37cbb32013-04-20 00:31:14 -0700321 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530322#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800323 }
324 else
325 {
326 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800327 "%s: Maximum peer connected already! %d",
328 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800329 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800330 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530331 }
Hoonki Leefb8df672013-04-10 18:20:34 -0700332 }
333 else if (eTDLS_LINK_CONNECTED == curr_peer->link_status) {
Chilam Ng01120412013-02-19 18:32:21 -0800334 if ((tANI_S32)curr_peer->rssi <
335 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800336
Chilam Ng01120412013-02-19 18:32:21 -0800337 VOS_TRACE( VOS_MODULE_ID_HDD,
338 VOS_TRACE_LEVEL_WARN,
339 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
340 MAC_ADDR_ARRAY(curr_peer->peerMac));
341#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700342 wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
343 curr_peer,
344 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Chilam Ng01120412013-02-19 18:32:21 -0800345#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800346 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530347 }
Chilam Ng01120412013-02-19 18:32:21 -0800348
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530349 /* Only teardown based on non zero idle packet threshold, to address a use
350 * case where this threshold does not get consider for TEAR DOWN.
351 */
352
353 if (( 0 != pHddTdlsCtx->threshold_config.idle_packet_n ) &&
354 ((curr_peer->tx_pkt <
Chilam Ng01120412013-02-19 18:32:21 -0800355 pHddTdlsCtx->threshold_config.idle_packet_n) &&
356 (curr_peer->rx_pkt <
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530357 pHddTdlsCtx->threshold_config.idle_packet_n))) {
Chilam Ng01120412013-02-19 18:32:21 -0800358 if (VOS_TIMER_STATE_RUNNING !=
359 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
361 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
362 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700363 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
364 &curr_peer->peerIdleTimer,
365 pHddTdlsCtx->threshold_config.idle_timeout_t);
Chilam Ng01120412013-02-19 18:32:21 -0800366 }
367 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800368 if (VOS_TIMER_STATE_RUNNING ==
369 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
371 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
372 MAC_ADDR_ARRAY(curr_peer->peerMac));
373 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800374 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800375 }
Chilam Ng01120412013-02-19 18:32:21 -0800376
Hoonki Leecdd8e962013-01-20 00:45:46 -0800377// if (curr_peer->rssi <
378// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
379// pHddTdlsCtx->ap_rssi)) {
380//
381//#ifdef CONFIG_TDLS_IMPLICIT
382// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
383// curr_peer->peerMac,
384// NL80211_TDLS_TEARDOWN, FALSE,
385// GFP_KERNEL);
386//#endif
387// }
Chilam NG571c65a2013-01-19 12:27:36 +0530388 }
Chilam Ng01120412013-02-19 18:32:21 -0800389 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530390
391 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
392 (FALSE == curr_peer->isForcedPeer)) {
393 continue;
394 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700395 if (!TDLS_IS_CONNECTED(curr_peer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800396 if (curr_peer->tx_pkt >=
397 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800398
Gopichand Nakkala062bcbd2013-03-29 18:14:47 -0700399 if (curr_peer->discovery_attempt++ <
Chilam Ng01120412013-02-19 18:32:21 -0800400 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700401 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Hoonki Leed37cbb32013-04-20 00:31:14 -0700402#ifdef CONFIG_TDLS_IMPLICIT
403 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
404#endif
Chilam Ng01120412013-02-19 18:32:21 -0800405 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800406 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800407 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800408 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800409 curr_peer->link_status = eTDLS_LINK_IDLE;
410 }
Chilam Ng01120412013-02-19 18:32:21 -0800411 }
412 }
Chilam NG571c65a2013-01-19 12:27:36 +0530413 }
414
Hoonki Leecdd8e962013-01-20 00:45:46 -0800415next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530416 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800417 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800418 }
Chilam NG571c65a2013-01-19 12:27:36 +0530419 }
420
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700421 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
422 &pHddTdlsCtx->peerUpdateTimer,
423 pHddTdlsCtx->threshold_config.tx_period_t);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530424 mutex_unlock(&pHddCtx->tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530425}
426
Chilam Ng1279e232013-01-25 15:06:52 -0800427static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
428{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800429#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800430 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530431 tdlsCtx_t *pHddTdlsCtx;
432 hdd_context_t *pHddCtx;
Chilam Ng1279e232013-01-25 15:06:52 -0800433
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700434 if (NULL == curr_peer)
435 {
436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530437 FL("Invalid tdls idle timer expired"));
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700438 return;
439 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530440 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
441
442 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530443 {
444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
445 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530446 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530447 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530448
449 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
450
c_hpothu7f63e882013-10-02 19:13:35 +0530451 if(0 != (wlan_hdd_validate_context(pHddCtx)))
452 {
453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
454 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530455 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530456 }
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700457
458 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800459 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d",
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700460 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
461 curr_peer->tx_pkt,
462 curr_peer->rx_pkt,
463 curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n);
464
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530465 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800466
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700467 /* Check tx/rx statistics on this tdls link for recent activities and
468 * then decide whether to tear down the link or keep it.
469 */
470 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))
471 {
472 /* this tdls link got back to normal, so keep it */
473 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
474 "%s: tdls link to " MAC_ADDRESS_STR " back to normal, will stay",
475 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
476 }
477 else
478 {
479 /* this tdls link needs to get torn down */
480 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
481 "%s: trigger tdls link to " MAC_ADDRESS_STR " down",
482 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
483
484 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
485 curr_peer,
486 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
487 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530488 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800489#endif
490}
491
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700492static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
493{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700494 int i;
495 struct list_head *head;
496 hddTdlsPeer_t *tmp;
497 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700498 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530499 hdd_context_t *pHddCtx;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700500
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530501 pHddTdlsCtx = (tdlsCtx_t *)userData;
502
503 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530504 {
505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
506 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530507 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530508 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530509
510 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
511
c_hpothu7f63e882013-10-02 19:13:35 +0530512 if(0 != (wlan_hdd_validate_context(pHddCtx)))
513 {
514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
515 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530516 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530517 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530518
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530519 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700520
521 for (i = 0; i < 256; i++) {
522 head = &pHddTdlsCtx->peer_list[i];
523 list_for_each_safe (pos, q, head) {
524 tmp = list_entry(pos, hddTdlsPeer_t, node);
525 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
526 {
527 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
528 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
529 MAC_ADDR_ARRAY(tmp->peerMac));
530 tmp->link_status = eTDLS_LINK_IDLE;
531 }
532 }
533 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700534
535 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700536 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700537
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530538 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700539
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700540 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
541
542 return;
543}
544
Hoonki Lee14621352013-04-16 17:51:19 -0700545static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
546{
547 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
548 tdlsCtx_t *pHddTdlsCtx;
549
550 if ( NULL == curr_peer )
c_hpothu7f63e882013-10-02 19:13:35 +0530551 {
552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
553 FL("curr_peer is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700554 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530555 }
Hoonki Lee14621352013-04-16 17:51:19 -0700556
557 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
558
559 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +0530560 {
561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
562 FL("pHddTdlsCtx is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700563 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530564 }
Hoonki Lee14621352013-04-16 17:51:19 -0700565
566 WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext,
567 (v_U8_t *)&curr_peer->staId);
568}
569
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800570static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800571{
572 int i;
573 struct list_head *head;
574 hddTdlsPeer_t *tmp;
575 struct list_head *pos, *q;
576
c_hpothu7f63e882013-10-02 19:13:35 +0530577 if (NULL == pHddTdlsCtx)
578 {
579 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
580 FL("pHddTdlsCtx is NULL"));
581 return;
582 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800583
584 for (i = 0; i < 256; i++) {
585 head = &pHddTdlsCtx->peer_list[i];
586 list_for_each_safe (pos, q, head) {
587 tmp = list_entry(pos, hddTdlsPeer_t, node);
588 list_del(pos);
589 vos_mem_free(tmp);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800590 tmp = NULL;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800591 }
592 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800593}
594
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700595static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
596{
597 tdls_scan_context_t *scan_ctx =
598 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
599
600 if (NULL == scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +0530601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 FL("scan_ctx is NULL"));
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700604 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530605 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700606
607 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
608 return;
609
610 scan_ctx->attempt++;
611
612 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
613#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
614 scan_ctx->dev,
615#endif
616 scan_ctx->scan_request);
617}
618
Agarwal Ashish4b87f922014-06-18 03:03:21 +0530619/* initialize TDLS global context */
620void wlan_hdd_tdls_init(hdd_context_t *pHddCtx )
621{
622 v_U8_t staIdx;
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700623
Agarwal Ashish4b87f922014-06-18 03:03:21 +0530624 pHddCtx->connected_peer_count = 0;
625
626 pHddCtx->tdls_scan_ctxt.magic = 0;
627 pHddCtx->tdls_scan_ctxt.attempt = 0;
628 pHddCtx->tdls_scan_ctxt.reject = 0;
629 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
630
631 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
632 {
633 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
634 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
635 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
636 sizeof(v_MACADDR_t)) ;
637 }
638
639 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
640 {
641 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
643 }
644 else
645 {
646 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
647 }
648}
649
650int wlan_hdd_sta_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800651{
Chilam Ng01120412013-02-19 18:32:21 -0800652 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700653 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800654 int i;
655
Sunil Dutt66485cb2013-12-19 19:05:03 +0530656 if (NULL == pHddCtx)
657 return -1;
658
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530659 mutex_lock(&pHddCtx->tdls_lock);
Sunil Dutt66485cb2013-12-19 19:05:03 +0530660
Hoonki Lee27511902013-03-14 18:19:06 -0700661 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
662 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
663 {
664 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
665 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
667 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
668 sme_IsFeatureSupportedByFW(TDLS));
Sunil Dutt66485cb2013-12-19 19:05:03 +0530669 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -0700670 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800671 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530672 /* TDLS is supported only in STA / P2P Client modes,
673 * hence the check for TDLS support in a specific Device mode.
674 * Do not return a failure rather do not continue further
675 * with the initialization as tdls_init would be called
676 * during the open adapter for a p2p interface at which point
677 * the device mode would be a P2P_DEVICE. The point here is to
678 * continue initialization for STA / P2P Client modes.
679 * TDLS exit also check for the device mode for clean up hence
680 * there is no issue even if success is returned.
681 */
682 if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter))
683 {
Sunil Dutt66485cb2013-12-19 19:05:03 +0530684 mutex_unlock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530685 return 0;
686 }
687 /* Check for the valid pHddTdlsCtx. If valid do not further
688 * allocate the memory, rather continue with the initialization.
689 * If tdls_initialization would get reinvoked without tdls_exit
690 * getting invoked (SSR) there is no point to further proceed
691 * with the memory allocations.
692 */
693 if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx)
694 {
695 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800696
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530697 if (NULL == pHddTdlsCtx) {
698 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
699 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
Sunil Dutt66485cb2013-12-19 19:05:03 +0530700 mutex_unlock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530701 return -1;
702 }
703 /* initialize TDLS pAdater context */
704 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
705#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
706 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
707 VOS_TIMER_TYPE_SW,
708 wlan_hdd_tdls_discover_peer_cb,
709 pHddTdlsCtx);
710#endif
Hoonki Lee27511902013-03-14 18:19:06 -0700711
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530712 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
713 VOS_TIMER_TYPE_SW,
714 wlan_hdd_tdls_update_peer_cb,
715 pHddTdlsCtx);
716 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
717 VOS_TIMER_TYPE_SW,
718 wlan_hdd_tdls_discovery_timeout_peer_cb,
719 pHddTdlsCtx);
720
721 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700722 }
723
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530724 pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700725
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700726 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700727
Hoonki Lee27511902013-03-14 18:19:06 -0700728 pHddTdlsCtx->pAdapter = pAdapter;
729
730 for (i = 0; i < 256; i++)
731 {
732 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
733 }
734
Hoonki Leed37cbb32013-04-20 00:31:14 -0700735 pHddTdlsCtx->curr_candidate = NULL;
736 pHddTdlsCtx->magic = 0;
737
Hoonki Lee27511902013-03-14 18:19:06 -0700738 /* remember configuration even if it is not used right now. it could be used later */
739 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
740 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
741 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
742 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
743 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
744 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
745 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
746 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
747 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530748
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700749 INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
750 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
Sunil Dutt66485cb2013-12-19 19:05:03 +0530751 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -0700752
753 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530754}
755
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800756void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530757{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800758 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700759 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800760
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530761 /*
762 * NOTE: The Callers of this function should ensure to acquire the
763 * tdls_lock to avoid any concurrent access to the Adapter.
764 */
765
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530766 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
c_hpothu7f63e882013-10-02 19:13:35 +0530767 if(0 != (wlan_hdd_validate_context(pHddCtx)))
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530768 {
Agarwal Ashishbf98caf2014-03-25 13:29:11 +0530769 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
c_hpothu7f63e882013-10-02 19:13:35 +0530770 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530771 return;
772 }
773
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800774 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800775 if (NULL == pHddTdlsCtx)
776 {
c_hpothu7f63e882013-10-02 19:13:35 +0530777 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
778 FL("pHddTdlsCtx is NULL"));
Hoonki Leebfee0342013-01-21 16:43:45 -0800779 return;
780 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700781#ifdef WLAN_OPEN_SOURCE
782 cancel_work_sync(&pHddTdlsCtx->implicit_setup);
783 cancel_delayed_work_sync(&pHddCtx->tdls_scan_ctxt.tdls_scan_work);
784#endif
Hoonki Leebfee0342013-01-21 16:43:45 -0800785
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800786 /* must stop timer here before freeing peer list, because peerIdleTimer is
787 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800788 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
789 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800790
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700791 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
792
Chilam Nga75d8b62013-01-29 01:35:59 -0800793 vos_mem_free(pHddTdlsCtx);
Pradeep Reddy POTTETI59c90d62014-03-24 19:45:47 +0530794 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
Chilam Nga75d8b62013-01-29 01:35:59 -0800795 pHddTdlsCtx = NULL;
Chilam NG571c65a2013-01-19 12:27:36 +0530796}
797
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530798/* stop all monitoring timers per Adapter */
799static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800800{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700801#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800802 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700803#endif
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800804 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700805 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530806}
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800807
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530808/* stop all per peer timers */
809static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx)
810{
811 int i;
812 struct list_head *head;
813 struct list_head *pos;
814 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800815 for (i = 0; i < 256; i++)
816 {
817 head = &pHddTdlsCtx->peer_list[i];
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800818 list_for_each (pos, head) {
819 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800820 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800821 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800822 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800823 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800824 vos_timer_stop ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700825 vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800826 }
827 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800828}
829
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530830/* stop all the tdls timers running */
831static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800832{
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530833 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
834 wlan_hdd_tdls_peer_timers_stop(pHddTdlsCtx);
835}
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800836
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530837static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
838{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700839#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800840 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
841 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700842#endif
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800843 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
844 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700845 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
846 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530847}
848/*Free all the timers related to the TDLS peer */
849static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
850{
851 int i;
852 struct list_head *head;
853 struct list_head *pos;
854 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800855 for (i = 0; i < 256; i++)
856 {
857 head = &pHddTdlsCtx->peer_list[i];
858
859 list_for_each (pos, head) {
860 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
861
862 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800863 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800864 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800865 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800866 vos_timer_stop ( &curr_peer->peerIdleTimer );
867 vos_timer_destroy ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700868 vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
869 vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800870 }
871 }
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530872
873}
874
875/* destroy all the tdls timers running */
876static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
877{
878 wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx);
879 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800880}
881
Hoonki Lee387663d2013-02-05 18:08:43 -0800882/* if mac address exist, return pointer
883 if mac address doesn't exist, create a list and add, return pointer
884 return NULL if fails to get new mac address
885*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800886hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530887{
Hoonki Lee387663d2013-02-05 18:08:43 -0800888 struct list_head *head;
889 hddTdlsPeer_t *peer;
890 u8 key;
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700891 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530892 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
893
c_hpothu7f63e882013-10-02 19:13:35 +0530894 if(0 != (wlan_hdd_validate_context(pHddCtx)))
895 {
896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
897 FL("pHddCtx is not valid"));
898 return 0;
899 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800900
Hoonki Lee387663d2013-02-05 18:08:43 -0800901 /* if already there, just update */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530902 peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -0800903 if (peer != NULL)
904 {
905 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530906 }
907
Hoonki Lee387663d2013-02-05 18:08:43 -0800908 /* not found, allocate and add the list */
909 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
910 if (NULL == peer) {
911 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
912 return NULL;
913 }
Chilam NG571c65a2013-01-19 12:27:36 +0530914
Rajesh Chauhana34c6e62014-03-25 16:37:58 +0530915 mutex_lock(&pHddCtx->tdls_lock);
916
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700917 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
918
919 if (NULL == pHddTdlsCtx)
920 {
c_hpothu7f63e882013-10-02 19:13:35 +0530921 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
922 FL("pHddTdlsCtx is NULL"));
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700923 vos_mem_free(peer);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530924 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700925 return NULL;
926 }
927
928 key = wlan_hdd_tdls_hash_key(mac);
929 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530930
Hoonki Lee387663d2013-02-05 18:08:43 -0800931 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
932 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800933 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800934
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800935 vos_timer_init(&peer->peerIdleTimer,
936 VOS_TIMER_TYPE_SW,
937 wlan_hdd_tdls_idle_cb,
938 peer);
939
Hoonki Lee14621352013-04-16 17:51:19 -0700940 vos_timer_init(&peer->initiatorWaitTimeoutTimer,
941 VOS_TIMER_TYPE_SW,
942 wlan_hdd_tdls_initiator_wait_cb,
943 peer);
944
Hoonki Lee387663d2013-02-05 18:08:43 -0800945 list_add_tail(&peer->node, head);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530946 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800947
948 return peer;
949}
950
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700951int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -0700952 u8* mac,
953 tTDLSCapType cap)
954{
955 hddTdlsPeer_t *curr_peer;
956
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700957 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -0700958 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +0530959 {
960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
961 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700962 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +0530963 }
Hoonki Lee27511902013-03-14 18:19:06 -0700964
965 curr_peer->tdls_support = cap;
966
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700967 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -0700968}
969
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800970void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800971{
972 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +0530973 {
974 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
975 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800976 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530977 }
Hoonki Lee387663d2013-02-05 18:08:43 -0800978
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800979 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800980 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530981
982 curr_peer->link_status = status;
983
Chilam NG571c65a2013-01-19 12:27:36 +0530984}
985
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800986void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
987 u8* mac,
988 tTDLSLinkStatus linkStatus)
989{
990 hddTdlsPeer_t *curr_peer;
991
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530992 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800993 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +0530994 {
995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
996 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800997 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530998 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800999
1000 curr_peer->link_status= linkStatus;
1001
1002 return;
1003}
1004
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001005int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301006{
1007 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001008 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301009 hdd_context_t *pHddCtx;
1010
1011 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +05301012 {
1013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1014 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301015 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301016 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301017
1018 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1019
c_hpothu7f63e882013-10-02 19:13:35 +05301020 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1021 {
1022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1023 FL("pHddCtx is not valid"));
1024 return 0;
1025 }
Chilam NG571c65a2013-01-19 12:27:36 +05301026
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001027 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001028
1029 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05301030 {
1031 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1032 FL("curr_peer is NULL"));
Hoonki Lee387663d2013-02-05 18:08:43 -08001033 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301034 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001035
1036 if (pHddTdlsCtx->discovery_sent_cnt)
1037 pHddTdlsCtx->discovery_sent_cnt--;
1038
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301039 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301040
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001041 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301042
1043 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001044 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001045 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001046 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001047 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001048
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001049 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001050 "Discovery(%u) Response from " MAC_ADDRESS_STR " link_status %d",
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001051 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
1052 curr_peer->link_status);
1053
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001054 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001055 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001056 /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI
1057 threshold is also met before setting up TDLS link*/
1058 if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold)
1059 {
1060 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
1061 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1062 "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" ,
1063 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1064 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
1065 cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL);
1066 }
1067 else
1068 {
1069 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1070 "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ",
1071 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1072 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
1073 curr_peer->link_status = eTDLS_LINK_IDLE;
1074 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001075 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001076 else
1077 {
1078 wlan_hdd_tdls_check_bmps(pAdapter);
1079 }
Chilam NG571c65a2013-01-19 12:27:36 +05301080
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001081 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -08001082 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301083}
1084
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301085int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter,
1086 u8 *mac,
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301087 tCsrStaParams *StaParams,
1088 tANI_BOOLEAN isBufSta,
1089 tANI_BOOLEAN isOffChannelSupported)
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301090{
1091 hddTdlsPeer_t *curr_peer;
1092
1093 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1094 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301095 {
1096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1097 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301098 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301099 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301100
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301101 curr_peer->uapsdQueues = StaParams->uapsd_queues;
1102 curr_peer->maxSp = StaParams->max_sp;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301103 curr_peer->isBufSta = isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301104 curr_peer->isOffChannelSupported = isOffChannelSupported;
1105
1106 vos_mem_copy(curr_peer->supported_channels,
1107 StaParams->supported_channels,
1108 StaParams->supported_channels_len);
1109
1110 curr_peer->supported_channels_len =
1111 StaParams->supported_channels_len;
1112
1113 vos_mem_copy(curr_peer->supported_oper_classes,
1114 StaParams->supported_oper_classes,
1115 StaParams->supported_oper_classes_len);
1116
1117 curr_peer->supported_oper_classes_len =
1118 StaParams->supported_oper_classes_len;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301119 return 0;
1120}
1121
1122int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac,
1123 tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams)
1124{
1125 hddTdlsPeer_t *curr_peer;
1126
1127 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1128 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301129 {
1130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1131 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301132 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301133 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301134
1135 tdlsLinkEstablishParams->isResponder = curr_peer->is_responder;
1136 tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues;
1137 tdlsLinkEstablishParams->maxSp = curr_peer->maxSp;
1138 tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301139 tdlsLinkEstablishParams->isOffChannelSupported =
1140 curr_peer->isOffChannelSupported;
1141
1142 vos_mem_copy(tdlsLinkEstablishParams->supportedChannels,
1143 curr_peer->supported_channels,
1144 curr_peer->supported_channels_len);
1145
1146 tdlsLinkEstablishParams->supportedChannelsLen =
1147 curr_peer->supported_channels_len;
1148
1149 vos_mem_copy(tdlsLinkEstablishParams->supportedOperClasses,
1150 curr_peer->supported_oper_classes,
1151 curr_peer->supported_oper_classes_len);
1152
1153 tdlsLinkEstablishParams->supportedOperClassesLen =
1154 curr_peer->supported_oper_classes_len;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301155 return 0;
1156}
1157
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001158int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +05301159{
1160 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +05301161
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301162 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -08001163 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301164 {
1165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1166 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001167 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301168 }
Chilam NG571c65a2013-01-19 12:27:36 +05301169
1170 curr_peer->rssi = rxRssi;
1171
Hoonki Lee387663d2013-02-05 18:08:43 -08001172 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301173}
1174
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001175int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08001176{
1177 hddTdlsPeer_t *curr_peer;
1178
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001179 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001180 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301181 {
1182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1183 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001184 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301185 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001186
1187 curr_peer->is_responder = responder;
1188
1189 return 0;
1190}
1191
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001192int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -08001193{
1194 hddTdlsPeer_t *curr_peer;
1195
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301196 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001197 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301198 {
1199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1200 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001201 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301202 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001203
1204 return (curr_peer->is_responder);
1205}
1206
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001207int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001208{
1209 hddTdlsPeer_t *curr_peer;
1210
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001211 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001212 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301213 {
1214 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1215 "%s: curr_peer is NULL", __func__);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001216 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301217 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001218
1219 curr_peer->signature = uSignature;
1220
1221 return 0;
1222}
1223
Hoonki Leea34dd892013-02-05 22:56:02 -08001224
Hoonki Lee387663d2013-02-05 18:08:43 -08001225void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301226{
Chilam NG571c65a2013-01-19 12:27:36 +05301227 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +05301228}
1229
Hoonki Lee387663d2013-02-05 18:08:43 -08001230void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -08001231{
Chilam Ng1279e232013-01-25 15:06:52 -08001232 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -08001233}
1234
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001235int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +05301236{
Hoonki Lee387663d2013-02-05 18:08:43 -08001237 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001238 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +05301239
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001240 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
1241 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -08001242
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001243 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001244 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301245 {
1246 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1247 "%s: curr_peer is NULL", __func__);
Chilam NG571c65a2013-01-19 12:27:36 +05301248 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301249 }
Chilam NG571c65a2013-01-19 12:27:36 +05301250
Chilam Ng1279e232013-01-25 15:06:52 -08001251 if (tx)
1252 curr_peer->tx_pkt++;
1253 else
1254 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +05301255
Chilam NG571c65a2013-01-19 12:27:36 +05301256 return 0;
1257}
1258
Hoonki Lee27511902013-03-14 18:19:06 -07001259static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
1260{
1261 if (config->tdls > 2)
1262 {
1263 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
1264 return -1;
1265 }
1266 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
1267 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
1268 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001269 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%ld>", __func__, config->tx_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001270 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
1271 return -1;
1272 }
1273 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
1274 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
1275 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001276 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%ld>", __func__, config->tx_packet_n,
Hoonki Lee27511902013-03-14 18:19:06 -07001277 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
1278 return -1;
1279 }
1280 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
1281 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
1282 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%ld>", __func__, config->discovery_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001284 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
1285 return -1;
1286 }
1287 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
1288 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
1289 {
1290 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
1291 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
1292 return -1;
1293 }
1294 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
1295 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
1296 {
1297 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
1298 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
1299 return -1;
1300 }
1301 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
1302 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
1303 {
1304 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
1305 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
1306 return -1;
1307 }
1308 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
1309 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
1310 {
1311 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
1312 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
1313 return -1;
1314 }
1315 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
1316 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
1317 {
1318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
1319 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
1320 return -1;
1321 }
1322 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
1323 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
1324 {
1325 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
1326 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
1327 return -1;
1328 }
1329 return 0;
1330}
1331
Chilam Ng01120412013-02-19 18:32:21 -08001332int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +05301333{
Chilam Ng01120412013-02-19 18:32:21 -08001334 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1335 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001336 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -07001337 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -08001338
Hoonki Lee27511902013-03-14 18:19:06 -07001339 if (NULL == pHddTdlsCtx)
1340 {
c_hpothu7f63e882013-10-02 19:13:35 +05301341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS not enabled!"));
Hoonki Lee27511902013-03-14 18:19:06 -07001342 return -1;
Chilam Ng01120412013-02-19 18:32:21 -08001343 }
Chilam NG571c65a2013-01-19 12:27:36 +05301344
Hoonki Lee27511902013-03-14 18:19:06 -07001345 if (wlan_hdd_tdls_check_config(config) != 0)
1346 {
1347 return -1;
1348 }
1349
1350 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1351 req_tdls_mode = config->tdls + 1;
1352 if (pHddCtx->tdls_mode == req_tdls_mode)
1353 {
1354 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1355 return -1;
1356 }
1357
1358 /* copy the configuration only when given tdls mode is implicit trigger enable */
1359 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1360 {
Chilam Ng01120412013-02-19 18:32:21 -08001361 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1362 }
Chilam NG571c65a2013-01-19 12:27:36 +05301363
Chilam Ng01120412013-02-19 18:32:21 -08001364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1365 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1366 config->tdls,
1367 config->tx_period_t,
1368 config->tx_packet_n,
1369 config->discovery_period_t,
1370 config->discovery_tries_n,
1371 config->idle_timeout_t,
1372 config->idle_packet_n,
1373 config->rssi_hysteresis,
1374 config->rssi_trigger_threshold,
1375 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301376
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001377 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE);
Chilam Ng01120412013-02-19 18:32:21 -08001378
Chilam NG571c65a2013-01-19 12:27:36 +05301379 return 0;
1380}
1381
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001382int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001383{
Hoonki Lee387663d2013-02-05 18:08:43 -08001384 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001385
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001386 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001387 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301388 {
1389 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1390 "%s: curr_peer is NULL", __func__);
Chilam NG571c65a2013-01-19 12:27:36 +05301391 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301392 }
Chilam NG571c65a2013-01-19 12:27:36 +05301393
Hoonki Lee387663d2013-02-05 18:08:43 -08001394 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301395
1396 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001397}
1398
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301399int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac,
1400 tANI_BOOLEAN forcePeer)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301401{
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301402 hddTdlsPeer_t *curr_peer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301403 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1404
1405 if ((NULL == pHddCtx)) return -1;
1406
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301407 mutex_lock(&pHddCtx->tdls_lock);
1408
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301409 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
1410 if (curr_peer == NULL)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301411 goto error;
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301412 curr_peer->isForcedPeer = forcePeer;
Naresh Jayaramca7bc3a2014-02-04 23:03:04 +05301413
1414 mutex_unlock(&pHddCtx->tdls_lock);
1415 return 0;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301416error:
1417 mutex_unlock(&pHddCtx->tdls_lock);
1418 return -1;
1419}
1420
Hoonki Lee387663d2013-02-05 18:08:43 -08001421/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1422 otherwise, it returns NULL
1423*/
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301424hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac,
1425 tANI_BOOLEAN mutexLock)
Kiran V1ccee932012-12-12 14:49:46 -08001426{
Hoonki Lee387663d2013-02-05 18:08:43 -08001427 u8 key;
1428 struct list_head *pos;
1429 struct list_head *head;
1430 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001431 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301432 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee387663d2013-02-05 18:08:43 -08001433
c_hpothu7f63e882013-10-02 19:13:35 +05301434 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1435 {
1436 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1437 FL("pHddCtx is not valid"));
1438 return 0;
1439 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001440
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301441 if ( mutexLock )
Hoonki Lee387663d2013-02-05 18:08:43 -08001442 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301443 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001444 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001445 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001446 if (NULL == pHddTdlsCtx)
1447 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301448 if ( mutexLock )
1449 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001450 return NULL;
1451 }
1452
1453 key = wlan_hdd_tdls_hash_key(mac);
1454
1455 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001456
1457 list_for_each(pos, head) {
1458 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1459 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1461 "findTdlsPeer: found staId %d", curr_peer->staId);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301462 if ( mutexLock )
1463 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001464 return curr_peer;
1465 }
1466 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301467 if ( mutexLock )
1468 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001469 return NULL;
1470}
1471
Hoonki Leea6d49be2013-04-05 09:43:25 -07001472hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac)
1473{
1474 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1475 hdd_adapter_t *pAdapter = NULL;
1476 tdlsCtx_t *pHddTdlsCtx = NULL;
1477 hddTdlsPeer_t *curr_peer= NULL;
1478 VOS_STATUS status = 0;
1479
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301480 mutex_lock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001481 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1482 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1483 {
1484 pAdapter = pAdapterNode->pAdapter;
1485
1486 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1487 if (NULL != pHddTdlsCtx)
1488 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301489 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001490 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301491 {
1492 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001493 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301494 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07001495 }
1496 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1497 pAdapterNode = pNext;
1498 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301499 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001500 return curr_peer;
1501}
1502
1503
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001504int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001505{
Chilam Ng01120412013-02-19 18:32:21 -08001506 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301507 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001508
Chilam Ng01120412013-02-19 18:32:21 -08001509 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1510
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001511 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001512 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301513 {
1514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1515 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001516 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301517 }
Chilam NG571c65a2013-01-19 12:27:36 +05301518
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001519 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001520 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001521
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301522 /* Throughput Monitor shall disable the split scan when
1523 * TDLS scan coexistance is disabled.At this point of time
1524 * since TDLS scan coexistance is not meeting the criteria
1525 * to be operational, explicitly make it false to enable
1526 * throughput monitor takes the control of split scan.
1527 */
1528 if (pHddCtx->isTdlsScanCoexistence == TRUE)
1529 {
1530 pHddCtx->isTdlsScanCoexistence = FALSE;
1531 }
1532
Chilam Ng01120412013-02-19 18:32:21 -08001533 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001534 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001535 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001536 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001537}
1538
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001539/* Caller has to take the lock before calling this function */
Hoonki Lee27511902013-03-14 18:19:06 -07001540static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1541{
1542 int i;
1543 struct list_head *head;
1544 hddTdlsPeer_t *tmp;
1545 struct list_head *pos, *q;
1546
Hoonki Lee27511902013-03-14 18:19:06 -07001547 for (i = 0; i < 256; i++) {
1548 head = &pHddTdlsCtx->peer_list[i];
1549 list_for_each_safe (pos, q, head) {
1550 tmp = list_entry(pos, hddTdlsPeer_t, node);
1551 tmp->tx_pkt = 0;
1552 tmp->rx_pkt = 0;
1553 }
1554 }
Hoonki Lee27511902013-03-14 18:19:06 -07001555
1556 return ;
1557}
1558
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001559/* Caller has to take the lock before calling this function */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001560static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001561{
1562 int i;
1563 struct list_head *head;
1564 hddTdlsPeer_t *tmp;
1565 struct list_head *pos, *q;
1566
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001567 pHddTdlsCtx->discovery_peer_cnt = 0;
1568
1569 for (i = 0; i < 256; i++) {
1570 head = &pHddTdlsCtx->peer_list[i];
1571 list_for_each_safe (pos, q, head) {
1572 tmp = list_entry(pos, hddTdlsPeer_t, node);
1573 tmp->discovery_processed = 0;
1574 }
1575 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001576
1577 return 0;
1578}
1579
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001580static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001581{
1582 int i;
1583 struct list_head *head;
1584 struct list_head *pos, *q;
1585 int discovery_peer_cnt=0;
1586 hddTdlsPeer_t *tmp;
1587
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001588 /*
1589 * This function expects the callers to acquire the Mutex.
1590 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001591
1592 for (i = 0; i < 256; i++) {
1593 head = &pHddTdlsCtx->peer_list[i];
1594 list_for_each_safe (pos, q, head) {
1595 tmp = list_entry(pos, hddTdlsPeer_t, node);
1596 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001597 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1598 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001599 discovery_peer_cnt++;
1600 }
1601 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001602 return discovery_peer_cnt;
1603}
1604
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001605tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001606{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001607 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1608
c_hpothu7f63e882013-10-02 19:13:35 +05301609 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1610 {
1611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1612 FL("pHddCtx is not valid"));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001613 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05301614 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08001615
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001616 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001617}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001618
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301619hddTdlsPeer_t *wlan_hdd_tdls_get_first_connected_peer(hdd_adapter_t *pAdapter)
1620{
1621 int i;
1622 struct list_head *head;
1623 struct list_head *pos;
1624 hddTdlsPeer_t *curr_peer = NULL;
1625 tdlsCtx_t *pHddTdlsCtx;
1626 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1627
1628 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1629 {
1630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1631 FL("pHddCtx is not valid"));
1632 return NULL;
1633 }
1634
1635 mutex_lock(&pHddCtx->tdls_lock);
1636 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1637 if (NULL == pHddTdlsCtx) {
1638 mutex_unlock(&pHddCtx->tdls_lock);
1639 return NULL;
1640 }
1641 for (i = 0; i < 256; i++) {
1642 head = &pHddTdlsCtx->peer_list[i];
1643
1644 list_for_each(pos, head) {
1645 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05301646 if (curr_peer && (curr_peer->link_status == eTDLS_LINK_CONNECTED))
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301647 {
1648 mutex_unlock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05301649 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1650 "%s: " MAC_ADDRESS_STR " eTDLS_LINK_CONNECTED",
1651 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05301652 return curr_peer;
1653 }
1654 }
1655 }
1656 mutex_unlock(&pHddCtx->tdls_lock);
1657 return NULL;
1658}
1659
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001660int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001661{
1662 int i;
1663 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001664 struct list_head *head;
1665 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001666 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001667 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301668 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1669
c_hpothu7f63e882013-10-02 19:13:35 +05301670 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1671 {
1672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1673 FL("pHddCtx is not valid"));
1674 return 0;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301675 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001676
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001677 init_len = buflen;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001678 len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n",
1679 "MAC", "Id", "cap", "up", "RSSI");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001680 buf += len;
1681 buflen -= len;
1682 /* 1234567890123456789012345678901234567 */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001683 len = scnprintf(buf, buflen, "---------------------------------\n");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001684 buf += len;
1685 buflen -= len;
1686
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301687 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001688 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001689 if (NULL == pHddTdlsCtx) {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301690 mutex_unlock(&pHddCtx->tdls_lock);
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001691 len = scnprintf(buf, buflen, "TDLS not enabled\n");
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001692 return len;
1693 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001694 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001695 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001696
Hoonki Lee387663d2013-02-05 18:08:43 -08001697 list_for_each(pos, head) {
1698 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001699
Hoonki Lee387663d2013-02-05 18:08:43 -08001700 if (buflen < 32+1)
1701 break;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001702 len = scnprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001703 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1704 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001705 curr_peer->staId,
1706 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001707 TDLS_IS_CONNECTED(curr_peer) ? "Y":"N",
Hoonki Lee387663d2013-02-05 18:08:43 -08001708 curr_peer->rssi);
1709 buf += len;
1710 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001711 }
1712 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301713 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001714 return init_len-buflen;
1715}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001716
1717void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1718{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001719 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301720 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001721
c_hpothu7f63e882013-10-02 19:13:35 +05301722 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1723 {
Agarwal Ashishbf98caf2014-03-25 13:29:11 +05301724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
1725 FL("pHddCtx or pHddTdlsCtx points to NULL"));
c_hpothu7f63e882013-10-02 19:13:35 +05301726 return;
1727 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301728
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301729 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001730
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001731 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1732 "%s, update %d discover %d", __func__,
1733 pHddTdlsCtx->threshold_config.tx_period_t,
1734 pHddTdlsCtx->threshold_config.discovery_period_t);
1735
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001736 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1737 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001738 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001739 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001740 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001741
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001742#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001743 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1744 &pHddTdlsCtx->peerDiscoverTimer,
1745 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001746#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001747 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1748 &pHddTdlsCtx->peerUpdateTimer,
1749 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001750 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301751 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001752
1753}
1754
1755void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1756{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001757 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301758 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1759
c_hpothu7f63e882013-10-02 19:13:35 +05301760 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1761 {
1762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1763 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
1764 return;
1765 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001766
1767 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1768
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301769 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001770 if (NULL == pHddTdlsCtx)
1771 {
c_hpothu7f63e882013-10-02 19:13:35 +05301772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1773 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301774 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001775 return;
1776 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001777 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001778 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001779
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301780 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
1781 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001782 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001783
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301784 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001785}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001786
1787void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1788{
1789 pAdapter->mgmtTxCompletionStatus = statusCode;
1790 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1791 __func__, statusCode);
1792 complete(&pAdapter->tdls_mgmt_comp);
1793}
1794
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001795void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001796{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001797 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001798
c_hpothu7f63e882013-10-02 19:13:35 +05301799 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1800 {
1801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1802 FL("pHddCtx is not valid"));
1803 return;
1804 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001805
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301806 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301807
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001808 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001809 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001810
1811 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1812 __func__, pHddCtx->connected_peer_count);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301813
1814 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001815}
1816
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001817void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001818{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001819 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001820
c_hpothu7f63e882013-10-02 19:13:35 +05301821 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1822 {
1823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1824 FL("pHddCtx is not valid"));
1825 return;
1826 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001827
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301828 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301829
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001830 if (pHddCtx->connected_peer_count)
1831 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001832 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001833
1834 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1835 __func__, pHddCtx->connected_peer_count);
1836
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301837 mutex_unlock(&pHddCtx->tdls_lock);
1838
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001839}
1840
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001841void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001842{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001843 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001844 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee14621352013-04-16 17:51:19 -07001845 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001846
c_hpothu7f63e882013-10-02 19:13:35 +05301847 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1848 {
1849 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1850 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
1851 return;
1852 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001853
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301854 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Lee14621352013-04-16 17:51:19 -07001855 if (NULL != curr_peer)
1856 {
1857 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1858 "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR,
1859 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac));
1860 return;
1861 }
1862
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001863 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
1864 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001865 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001866 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001867 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1868 {
1869 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001870 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1871 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001872 hdd_enable_bmps_imps(pHddCtx);
1873 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001874 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001875 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001876 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001877 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1878 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001879 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1880 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001881 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1882 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001883 }
1884 return;
1885}
1886
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001887u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
1888{
1889 hddTdlsPeer_t *curr_peer;
1890
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301891 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001892 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301893 {
1894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1895 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001896 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05301897 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001898
1899 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
1900}
1901
Hoonki Leefb8df672013-04-10 18:20:34 -07001902/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL.
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001903 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1904 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1905 mac is NULL, this argument is ignored, and check for all the peer list.
1906 */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301907static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001908{
1909 int i;
1910 struct list_head *head;
1911 hddTdlsPeer_t *curr_peer;
1912 struct list_head *pos;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301913 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301914
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301915 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05301916 {
1917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1918 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301919 return NULL;
c_hpothu7f63e882013-10-02 19:13:35 +05301920 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301921
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001922 for (i = 0; i < 256; i++) {
1923 head = &pHddTdlsCtx->peer_list[i];
1924 list_for_each(pos, head) {
1925 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1926 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1927 continue;
1928 }
1929 else
1930 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001931 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001932 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001933 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001934 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001935 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Hoonki Leefb8df672013-04-10 18:20:34 -07001936 return curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001937 }
1938 }
1939 }
1940 }
Hoonki Leefb8df672013-04-10 18:20:34 -07001941 return NULL;
1942}
1943
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301944hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8 *mac, u8 skip_self)
Hoonki Leefb8df672013-04-10 18:20:34 -07001945{
1946 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1947 hdd_adapter_t *pAdapter = NULL;
1948 tdlsCtx_t *pHddTdlsCtx = NULL;
1949 hddTdlsPeer_t *curr_peer= NULL;
1950 VOS_STATUS status = 0;
1951
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05301952 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301953
Hoonki Leefb8df672013-04-10 18:20:34 -07001954 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1955 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1956 {
1957 pAdapter = pAdapterNode->pAdapter;
1958
1959 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1960 if (NULL != pHddTdlsCtx)
1961 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301962 curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self);
Hoonki Leefb8df672013-04-10 18:20:34 -07001963 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301964 {
1965 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001966 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301967 }
Hoonki Leefb8df672013-04-10 18:20:34 -07001968 }
1969 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1970 pAdapterNode = pNext;
1971 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301972 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001973 return NULL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001974}
Hoonki Lee27511902013-03-14 18:19:06 -07001975
1976static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1977{
Hoonki Lee27511902013-03-14 18:19:06 -07001978 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07001979}
1980
1981static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1982{
1983 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001984 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001985 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001986 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001987
Hoonki Lee27511902013-03-14 18:19:06 -07001988
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001989#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001990 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1991 &pHddTdlsCtx->peerDiscoverTimer,
1992 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001993#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001994 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1995 &pHddTdlsCtx->peerUpdateTimer,
1996 pHddTdlsCtx->threshold_config.tx_period_t);
Hoonki Lee27511902013-03-14 18:19:06 -07001997}
1998
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001999void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
2000 eTDLSSupportMode tdls_mode,
2001 v_BOOL_t bUpdateLast)
Hoonki Lee27511902013-03-14 18:19:06 -07002002{
2003 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2004 VOS_STATUS status;
2005 hdd_adapter_t *pAdapter;
2006 tdlsCtx_t *pHddTdlsCtx;
2007
2008 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
c_hpothu7f63e882013-10-02 19:13:35 +05302009
2010 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2011 {
2012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2013 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302014 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302015 }
Hoonki Lee27511902013-03-14 18:19:06 -07002016
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302017 mutex_lock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07002018
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002019 if (pHddCtx->tdls_mode == tdls_mode)
2020 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002021 hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302022 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002023 return;
2024 }
2025
Hoonki Lee27511902013-03-14 18:19:06 -07002026 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2027
2028 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2029 {
2030 pAdapter = pAdapterNode->pAdapter;
Hoonki Leea6d49be2013-04-05 09:43:25 -07002031 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2032 if (NULL != pHddTdlsCtx)
Hoonki Lee27511902013-03-14 18:19:06 -07002033 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002034 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
2035 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
2036 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
2037 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
2038 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07002039 }
2040 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2041 pAdapterNode = pNext;
2042 }
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002043 if(bUpdateLast)
2044 {
2045 pHddCtx->tdls_mode_last = tdls_mode;
2046 }
2047 else
2048 {
2049 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
2050 }
Hoonki Lee27511902013-03-14 18:19:06 -07002051 pHddCtx->tdls_mode = tdls_mode;
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002052
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302053 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -07002054}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002055
Hoonki Leed37cbb32013-04-20 00:31:14 -07002056static void wlan_hdd_tdls_pre_setup(struct work_struct *work)
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002057{
Hoonki Leed37cbb32013-04-20 00:31:14 -07002058 tdlsCtx_t *pHddTdlsCtx =
2059 container_of(work, tdlsCtx_t, implicit_setup);
2060 hdd_context_t *pHddCtx;
2061 hddTdlsPeer_t *curr_peer;
Hoonki Leefb8df672013-04-10 18:20:34 -07002062 hddTdlsPeer_t *temp_peer;
Hoonki Leed37cbb32013-04-20 00:31:14 -07002063 int status;
2064
2065 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302066 {
2067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2068 FL("pHddTdlsCtx is NULL"));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002069 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302070 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002071
2072 if (unlikely(TDLS_CTX_MAGIC != pHddTdlsCtx->magic))
c_hpothu7f63e882013-10-02 19:13:35 +05302073 {
2074 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2075 "%s: tdls magic no missmatch %u", __func__, pHddTdlsCtx->magic);
Hoonki Leed37cbb32013-04-20 00:31:14 -07002076 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302077 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002078
2079 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
Hoonki Leefb8df672013-04-10 18:20:34 -07002080
c_hpothu7f63e882013-10-02 19:13:35 +05302081 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2082 {
2083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2084 FL("pHddCtx is not valid"));
Hoonki Leefb8df672013-04-10 18:20:34 -07002085 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302086 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002087
Hoonki Leed37cbb32013-04-20 00:31:14 -07002088 curr_peer = pHddTdlsCtx->curr_candidate;
2089
2090 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302091 {
2092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2093 FL("curr_peer is NULL"));
2094
Hoonki Leed37cbb32013-04-20 00:31:14 -07002095 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302096 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002097
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002098 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
2099 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002100 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002101 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
2102 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002103
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302104 temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002105 if (NULL != temp_peer)
2106 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002107 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored",
Hoonki Leefb8df672013-04-10 18:20:34 -07002108 __func__, MAC_ADDR_ARRAY(temp_peer->peerMac));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002109 goto done;
Hoonki Leefb8df672013-04-10 18:20:34 -07002110 }
2111
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002112 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
2113 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
2114
Hoonki Leed37cbb32013-04-20 00:31:14 -07002115 status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy,
2116 pHddTdlsCtx->pAdapter->dev,
2117 curr_peer->peerMac);
2118
2119 if (0 != status)
2120 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002121 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " discovery could not sent",
Hoonki Leed37cbb32013-04-20 00:31:14 -07002122 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
2123 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
2124 curr_peer->link_status = eTDLS_LINK_IDLE;
2125 goto done;
2126 }
2127
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002128 pHddTdlsCtx->discovery_sent_cnt++;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302129
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05302130 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302131
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002132 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302133
2134 mutex_unlock(&pHddCtx->tdls_lock);
Jeff Johnson0299d0a2013-10-30 12:37:43 -07002135 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %u timeout %u msec",
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002136 __func__, pHddTdlsCtx->discovery_sent_cnt,
2137 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002138
2139 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
2140 &pHddTdlsCtx->peerDiscoveryTimeoutTimer,
2141 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002142
Hoonki Leed37cbb32013-04-20 00:31:14 -07002143done:
2144 pHddTdlsCtx->curr_candidate = NULL;
2145 pHddTdlsCtx->magic = 0;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002146 return;
2147}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002148
2149tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
2150{
2151 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2152 hdd_adapter_t *pAdapter = NULL;
2153 tdlsCtx_t *pHddTdlsCtx = NULL;
2154 VOS_STATUS status = 0;
2155 tANI_U32 count = 0;
2156
2157 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2158 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2159 {
2160 pAdapter = pAdapterNode->pAdapter;
2161
Hoonki Leea6d49be2013-04-05 09:43:25 -07002162 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2163 if (NULL != pHddTdlsCtx)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002164 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002165 count = count + pHddTdlsCtx->discovery_sent_cnt;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002166 }
2167 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2168 pAdapterNode = pNext;
2169 }
2170 return count;
2171}
2172
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002173void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002174{
2175 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2176 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2177
2178 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
c_hpothu7f63e882013-10-02 19:13:35 +05302179 {
2180 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2181 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002182 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302183 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002184
2185 if ((0 == pHddCtx->connected_peer_count) &&
2186 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
2187 {
2188 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
2189 return;
2190 }
2191 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
2192 return;
2193}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002194
2195void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
2196{
2197 if (NULL == tdls_scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +05302198 {
2199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2200 FL("tdls_scan_ctx is NULL"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002201 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302202 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002203
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002204 tdls_scan_ctx->attempt = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -07002205 tdls_scan_ctx->reject = 0;
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002206 tdls_scan_ctx->magic = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002207 tdls_scan_ctx->scan_request = NULL;
2208 return;
2209}
2210
2211int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
2212 struct wiphy *wiphy,
2213#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2214 struct net_device *dev,
2215#endif
2216 struct cfg80211_scan_request *request)
2217{
2218 tdls_scan_context_t *scan_ctx;
2219
c_hpothu7f63e882013-10-02 19:13:35 +05302220 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2221 {
2222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2223 FL("pHddCtx is not valid"));
2224 return 0;
2225 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002226
2227 scan_ctx = &pHddCtx->tdls_scan_ctxt;
2228
2229 scan_ctx->wiphy = wiphy;
2230#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2231 scan_ctx->dev = dev;
2232#endif
2233
2234 scan_ctx->scan_request = request;
2235 return 0;
2236}
2237
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002238static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
2239 struct wiphy *wiphy,
2240#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2241 struct net_device *dev,
2242#endif
2243 struct cfg80211_scan_request *request,
2244 unsigned long delay)
2245{
2246 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
2247 {
2248#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2249 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
2250#else
2251 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
2252#endif
2253 pHddCtx->tdls_scan_ctxt.attempt = 0;
2254 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
2255 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002256 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
2257}
2258
2259/* return negative = caller should stop and return error code immediately
2260 return 0 = caller should stop and return success immediately
2261 return 1 = caller can continue to scan
2262 */
2263int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
2264 struct wiphy *wiphy,
2265#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2266 struct net_device *dev,
2267#endif
2268 struct cfg80211_scan_request *request)
2269{
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002270 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2271 u16 connectedTdlsPeers;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302272 hddTdlsPeer_t *curr_peer, *connected_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002273 unsigned long delay;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302274 hdd_config_t *cfg_param = pHddCtx->cfg_ini;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002275
c_hpothu7f63e882013-10-02 19:13:35 +05302276 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2277 {
2278 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2279 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002280 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05302281 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002282
2283 /* if tdls is not enabled, then continue scan */
2284 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
2285 return 1;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302286 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002287 if (NULL != curr_peer)
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002288 {
Hoonki Leefb8df672013-04-10 18:20:34 -07002289 if (pHddCtx->tdls_scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT)
2290 {
2291 pHddCtx->tdls_scan_ctxt.reject = 0;
2292 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2293 "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle",
2294 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->tdls_scan_ctxt.reject);
2295
2296 wlan_hdd_tdls_set_peer_link_status (curr_peer, eTDLS_LINK_IDLE);
2297 return 1;
2298 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002299 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Leefb8df672013-04-10 18:20:34 -07002300 "%s: tdls in progress. scan rejected %d",
2301 __func__, pHddCtx->tdls_scan_ctxt.reject);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002302 return -EBUSY;
2303 }
2304
2305 /* tdls teardown is ongoing */
2306 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
2307 {
2308 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2309 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
2310 {
2311 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2312 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2313 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
2314 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
2315
2316 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2317#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2318 dev,
2319#endif
2320 request,
2321 msecs_to_jiffies(delay));
2322 /* scan should not continue */
2323 return 0;
2324 }
2325 /* no connected peer or max retry reached, scan continue */
2326 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2327 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
2328 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
2329 return 1;
2330 }
2331 /* while tdls is up, first time scan */
2332 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
2333 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
2334 {
2335 /* disable implicit trigger logic & tdls operatoin */
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002336 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002337 /* indicate the teardown all connected to peer */
2338 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302339
2340 /* check the TDLS link and Scan coexistance Capability */
2341 if ( (TRUE == pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport) &&
2342 (TRUE == sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE)) &&
2343 (connectedTdlsPeers == 1) )
2344 {
2345 /* get connected peer information */
2346 connected_peer = wlan_hdd_tdls_get_first_connected_peer(pAdapter);
2347 if (NULL == connected_peer) {
2348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
2349 "%s: Invalid connected_peer, Continue Scanning", __func__);
2350 /* scan should continue */
2351 return 1;
2352 }
2353 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2354 ("%s: TDLS Scan Co-exist supported connectedTdlsPeers =%d buffersta =%d"),
2355 __func__,connectedTdlsPeers,connected_peer->isBufSta);
2356
2357 if (connected_peer->isBufSta)
2358 {
2359 pHddCtx->isTdlsScanCoexistence = TRUE;
2360 if ((cfg_param->dynSplitscan) && (!pHddCtx->issplitscan_enabled))
2361 {
2362 pHddCtx->issplitscan_enabled = TRUE;
2363 sme_enable_disable_split_scan(
2364 WLAN_HDD_GET_HAL_CTX(pAdapter),
2365 cfg_param->nNumStaChanCombinedConc,
2366 cfg_param->nNumP2PChanCombinedConc);
2367 }
2368 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2369 ("%s:%d TDLS Scan Co-exist supported splitscan_enabled =%d "),
2370 __func__, __LINE__, pHddCtx->issplitscan_enabled);
2371 return 1;
2372 }
2373
2374 }
2375 else
2376 {
2377 /* Throughput Monitor shall disable the split scan when
2378 * TDLS scan coexistance is disabled.At this point of time
2379 * since TDLS scan coexistance is not meeting the criteria
2380 * to be operational, explicitly make it false to enable
2381 * throughput monitor takes the control of split scan.
2382 */
2383 pHddCtx->isTdlsScanCoexistence = FALSE;
2384 }
2385 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2386 ("%s: TDLS Scan Co-exist not supported connectedTdlsPeers =%d"
2387 " TDLSScanCoexSupport param =%d TDLS_SCAN_COEXISTENCE =%d"),
2388 __func__, connectedTdlsPeers,
2389 pHddCtx->cfg_ini->fEnableTDLSScanCoexSupport,
2390 sme_IsFeatureSupportedByFW(TDLS_SCAN_COEXISTENCE));
2391
2392 /* fall back to the implementation of teardown the peers on the scan
2393 * when the number of connected peers are more than one. TDLS Scan
2394 * coexistance feature is exercised only when a single peer is
2395 * connected and the DUT shall not advertize the Buffer Sta capability,
2396 * so that the peer shall not go to the TDLS power save
2397 */
2398
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002399 if (connectedTdlsPeers)
2400 {
2401 tANI_U8 staIdx;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002402 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002403
2404 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
2405 {
2406 if (pHddCtx->tdlsConnInfo[staIdx].staId)
2407 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002408 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002409 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
2410
2411#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leea6d49be2013-04-05 09:43:25 -07002412 curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
2413 if(curr_peer)
2414 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002415#endif
2416 }
2417 }
2418 /* schedule scan */
2419 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2420
2421 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2422 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
2423 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
2424 delay);
2425
2426 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2427#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2428 dev,
2429#endif
2430 request,
2431 msecs_to_jiffies(delay));
2432 /* scan should not continue */
2433 return 0;
2434 }
2435 /* no connected peer, scan continue */
2436 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2437 "%s: tdls_mode %d, and no tdls connection. scan allowed",
2438 __func__, pHddCtx->tdls_mode);
2439 }
2440 return 1;
2441}
2442
2443void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
2444{
2445 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002446
c_hpothu7f63e882013-10-02 19:13:35 +05302447 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2448 {
2449 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2450 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002451 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302452 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002453
Sunil Dutt41de4e22013-11-14 18:09:02 +05302454
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002455 /* free allocated memory at scan time */
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002456 wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002457
2458 /* if tdls was enabled before scan, re-enable tdls mode */
2459 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
2460 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
2461 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002462 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002463 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
2464
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002465 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002466 }
2467 wlan_hdd_tdls_check_bmps(pAdapter);
2468}
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002469
2470void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
2471 vos_timer_t *timer,
2472 v_U32_t expirationTime)
2473{
2474 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2475
2476 if (NULL == pHddStaCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302477 {
2478 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2479 FL("pHddStaCtx is NULL"));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002480 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302481 }
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002482
2483 /* Check whether driver load unload is in progress */
2484 if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
2485 {
2486 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2487 "%s: Driver load/unload is in progress.", __func__);
2488 return;
2489 }
2490
2491 if (hdd_connIsConnected(pHddStaCtx))
2492 {
2493 vos_timer_stop(timer);
2494 vos_timer_start(timer, expirationTime);
2495 }
2496}
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002497void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
2498 hddTdlsPeer_t *curr_peer,
2499 tANI_U16 reason)
2500{
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302501 hdd_context_t *pHddCtx;
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302502
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002503 if (NULL == pAdapter || NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302504 {
2505 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2506 FL("parameters passed are invalid"));
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002507 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302508 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002509
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302510 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2511
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002512 if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
2513 return;
2514
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302515 /* Throughput Monitor shall disable the split scan when
2516 * TDLS scan coexistance is disabled.At this point of time
2517 * since TDLS scan coexistance is not meeting the criteria
2518 * to be operational, explicitly make it false to enable
2519 * throughput monitor takes the control of split scan.
2520 */
Pradeep Reddy POTTETI8a623132014-06-26 16:07:06 +05302521 if (pHddCtx && (pHddCtx->isTdlsScanCoexistence == TRUE))
Pradeep Reddy POTTETIedaeb5f2014-05-22 23:34:41 +05302522 {
2523 pHddCtx->isTdlsScanCoexistence = FALSE;
2524 }
2525
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002526 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING);
2527 cfg80211_tdls_oper_request(pAdapter->dev,
2528 curr_peer->peerMac,
2529 NL80211_TDLS_TEARDOWN,
2530 reason,
2531 GFP_KERNEL);
2532}