blob: ca9971271c255ae5d0da6b319556fa593e97b3b6 [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Gopichand Nakkala0c1331e2013-01-07 22:49:07 -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.
20 */
Kiran V1ccee932012-12-12 14:49:46 -080021
22/**========================================================================
23
24 \file wlan_hdd_tdls.c
25
Chilam NG571c65a2013-01-19 12:27:36 +053026 \brief WLAN Host Device Driver implementation for TDLS
Kiran V1ccee932012-12-12 14:49:46 -080027
Kiran V1ccee932012-12-12 14:49:46 -080028 ========================================================================*/
29
30#include <wlan_hdd_includes.h>
31#include <wlan_hdd_hostapd.h>
32#include <net/cfg80211.h>
33#include <linux/netdevice.h>
34#include <linux/skbuff.h>
Chilam NG571c65a2013-01-19 12:27:36 +053035#include <linux/list.h>
Kiran V1ccee932012-12-12 14:49:46 -080036#include <linux/etherdevice.h>
37#include <net/ieee80211_radiotap.h>
38#include "wlan_hdd_tdls.h"
Chilam NG571c65a2013-01-19 12:27:36 +053039#include "wlan_hdd_cfg80211.h"
Kiran V1ccee932012-12-12 14:49:46 -080040
Chilam NG571c65a2013-01-19 12:27:36 +053041
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080042static struct mutex tdls_lock;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080043static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
44static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
45static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053046
Hoonki Lee5a4b2172013-01-29 01:45:53 -080047#ifndef WLAN_FEATURE_TDLS_DEBUG
48#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
49#else
50#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN
51#endif
52
Hoonki Lee387663d2013-02-05 18:08:43 -080053static u8 wlan_hdd_tdls_hash_key (u8 *mac)
Hoonki Leef63df0d2013-01-16 19:29:14 -080054{
55 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -080056 u8 key = 0;
57
58 for (i = 0; i < 6; i++)
59 key ^= mac[i];
60
61 return key;
62}
63
Gopichand Nakkala4327a152013-03-04 23:22:42 -080064static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx,
65 tANI_BOOLEAN mutexLock,
66 v_U32_t discoveryExpiry)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080067{
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080068 hdd_station_ctx_t *pHddStaCtx;
69
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080070 if ( mutexLock )
71 {
72 if (mutex_lock_interruptible(&tdls_lock))
73 {
74 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
75 "%s: unable to lock list: %d", __func__, __LINE__);
76 return;
77 }
78 }
79 if (NULL == pHddTdlsCtx)
80 {
81 if ( mutexLock )
82 mutex_unlock(&tdls_lock);
83 return;
84 }
85
Gopichand Nakkala4327a152013-03-04 23:22:42 -080086 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080087 {
88 if ( mutexLock )
89 mutex_unlock(&tdls_lock);
90 return;
91 }
92
Gopichand Nakkala4327a152013-03-04 23:22:42 -080093 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080094 if (hdd_connIsConnected( pHddStaCtx ))
95 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -070096#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080097 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer, discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -070098#endif
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
100 pHddTdlsCtx->ap_rssi);
101 }
102 if ( mutexLock )
103 mutex_unlock(&tdls_lock);
104
105 return;
106}
107
Hoonki Lee387663d2013-02-05 18:08:43 -0800108static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
109{
110 int i;
111 struct list_head *head;
112 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530113 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800114 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800115 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800116 int discover_req_sent = 0;
117 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800118 tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800119
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800120 if (mutex_lock_interruptible(&tdls_lock))
121 {
122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
123 "%s: unable to lock list : %d", __func__, __LINE__);
124 return;
125 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800126
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800127 if (NULL == pHddTdlsCtx)
128 {
129 mutex_unlock(&tdls_lock);
130 return;
131 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800132
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800133 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800134 {
135 mutex_unlock(&tdls_lock);
136 return;
137 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800138
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800139 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800140
Hoonki Lee387663d2013-02-05 18:08:43 -0800141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
142
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800143 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800144 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800145
Chilam NG571c65a2013-01-19 12:27:36 +0530146 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800147 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530148
Hoonki Lee387663d2013-02-05 18:08:43 -0800149 list_for_each (pos, head) {
150 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530151
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800152 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800153 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
154 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800155 curr_peer->discovery_processed,
156 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800157 curr_peer->tdls_support,
158 curr_peer->link_status,
159 curr_peer->discovery_attempt,
160 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800161
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800162 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
163 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530164
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800165 curr_peer->discovery_processed = 1;
166 discover_req_sent++;
167 pHddTdlsCtx->discovery_peer_cnt--;
168
169 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800170 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800171 (curr_peer->tx_pkt >=
172 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800173
174 if (curr_peer->discovery_attempt <
175 pHddTdlsCtx->threshold_config.discovery_tries_n) {
176
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800178 "sme_SendTdlsMgmtFrame(%d)", pHddTdlsCtx->pAdapter->sessionId);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800179
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800180 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
181 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800182 curr_peer->peerMac,
183 WLAN_TDLS_DISCOVERY_REQUEST,
184 1, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800185 curr_peer->discovery_attempt++;
186 }
187 else
188 {
189 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
190 "%s: Maximum Discovery retries reached", __func__);
191 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
192 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800193
194 }
195 }
Chilam NG571c65a2013-01-19 12:27:36 +0530196 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800197 else
198 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800199 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800200 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800201exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800202
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800203 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
204 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
205 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
206 pHddTdlsCtx->discovery_peer_cnt);
207 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800208 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800209 goto done;
210 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800211 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
212
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800213 mutex_unlock(&tdls_lock);
214
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800215 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530216
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800217 /* Commenting out the following function as it was introducing
218 * a race condition when pHddTdlsCtx is deleted. Also , this
219 * function is consuming more time in the timer callback.
220 * RSSI based trigger needs to revisit this part of the code.
221 */
222
223 /*
224 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
225 */
Chilam NG571c65a2013-01-19 12:27:36 +0530226
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800227done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800228 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800229
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800230 if ( !doMutexLock )
231 mutex_unlock(&tdls_lock);
232 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800233}
Chilam NG571c65a2013-01-19 12:27:36 +0530234
Hoonki Lee387663d2013-02-05 18:08:43 -0800235static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530236{
237 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800238 struct list_head *head;
239 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530240 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800241 tdlsCtx_t *pHddTdlsCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800242
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800243 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800244 {
245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
246 "%s: unable to lock list", __func__);
247 return;
248 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800249 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800250 if (NULL == pHddTdlsCtx)
251 {
252 mutex_unlock(&tdls_lock);
253 return;
254 }
255
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800256 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800257 {
258 mutex_unlock(&tdls_lock);
259 return;
260 }
261
Chilam NG571c65a2013-01-19 12:27:36 +0530262 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800263 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530264
Hoonki Lee387663d2013-02-05 18:08:43 -0800265 list_for_each (pos, head) {
266 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530267
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800268 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700269 "hdd update cb " MAC_ADDRESS_STR " link_status %d"
270 " tdls_support %d", MAC_ADDR_ARRAY(curr_peer->peerMac),
271 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800272
Chilam NG571c65a2013-01-19 12:27:36 +0530273 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800274 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800275 "%s: (tx %d, rx %d, config %d) " MAC_ADDRESS_STR " (%d) ",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800276 __func__, curr_peer->tx_pkt, curr_peer->rx_pkt,
277 pHddTdlsCtx->threshold_config.tx_packet_n,
Chilam Ng01120412013-02-19 18:32:21 -0800278 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->link_status);
279
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800280 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
281 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Chilam NG571c65a2013-01-19 12:27:36 +0530282 if (curr_peer->tx_pkt >=
283 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800284
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800285 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800286 {
287
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700288 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530289#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700290 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530291#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800292 }
293 else
294 {
295 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800296 "%s: Maximum peer connected already! %d",
297 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800298 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800299 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530300 }
Gopichand Nakkala9f7592a2013-02-27 12:41:50 -0800301 if ((((tANI_S32)curr_peer->rssi >
Hoonki Leecdd8e962013-01-20 00:45:46 -0800302 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis +
Gopichand Nakkala9f7592a2013-02-27 12:41:50 -0800303 pHddTdlsCtx->ap_rssi)) ||
304 ((tANI_S32)(curr_peer->rssi >
305 pHddTdlsCtx->threshold_config.rssi_trigger_threshold))) &&
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800306 (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))){
Chilam NG571c65a2013-01-19 12:27:36 +0530307
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800308 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
309 "%s: RSSI (peer %d > ap %d + hysteresis %d) triggering to %02x:%02x:%02x:%02x:%02x:%02x ",
310 __func__, (tANI_S32)curr_peer->rssi,
311 pHddTdlsCtx->ap_rssi,
312 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis),
313 curr_peer->peerMac[0], curr_peer->peerMac[1], curr_peer->peerMac[2],
314 curr_peer->peerMac[3], curr_peer->peerMac[4], curr_peer->peerMac[5]);
Chilam NG571c65a2013-01-19 12:27:36 +0530315
316#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800317 cfg80211_tdls_oper_request(pHddTdlsCtx->pAdapter->dev,
Chilam NG571c65a2013-01-19 12:27:36 +0530318 curr_peer->peerMac,
319 NL80211_TDLS_SETUP, FALSE,
320 GFP_KERNEL);
321#endif
322 }
323 } else {
Chilam Ng01120412013-02-19 18:32:21 -0800324 if ((tANI_S32)curr_peer->rssi <
325 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800326
Chilam Ng01120412013-02-19 18:32:21 -0800327 VOS_TRACE( VOS_MODULE_ID_HDD,
328 VOS_TRACE_LEVEL_WARN,
329 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
330 MAC_ADDR_ARRAY(curr_peer->peerMac));
331#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800332 cfg80211_tdls_oper_request(pHddTdlsCtx->pAdapter->dev,
Chilam Ng01120412013-02-19 18:32:21 -0800333 curr_peer->peerMac,
334 NL80211_TDLS_TEARDOWN, FALSE,
335 GFP_KERNEL);
336#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800337 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530338 }
Chilam Ng01120412013-02-19 18:32:21 -0800339
340 if ((curr_peer->tx_pkt <
341 pHddTdlsCtx->threshold_config.idle_packet_n) &&
342 (curr_peer->rx_pkt <
343 pHddTdlsCtx->threshold_config.idle_packet_n)) {
344 if (VOS_TIMER_STATE_RUNNING !=
345 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
347 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
348 MAC_ADDR_ARRAY(curr_peer->peerMac));
349 vos_timer_start( &curr_peer->peerIdleTimer,
350 pHddTdlsCtx->threshold_config.idle_timeout_t );
351 }
352 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800353 if (VOS_TIMER_STATE_RUNNING ==
354 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800355 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
356 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
357 MAC_ADDR_ARRAY(curr_peer->peerMac));
358 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800359 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800360 }
Chilam Ng01120412013-02-19 18:32:21 -0800361
Hoonki Leecdd8e962013-01-20 00:45:46 -0800362// if (curr_peer->rssi <
363// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
364// pHddTdlsCtx->ap_rssi)) {
365//
366//#ifdef CONFIG_TDLS_IMPLICIT
367// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
368// curr_peer->peerMac,
369// NL80211_TDLS_TEARDOWN, FALSE,
370// GFP_KERNEL);
371//#endif
372// }
Chilam NG571c65a2013-01-19 12:27:36 +0530373 }
Chilam Ng01120412013-02-19 18:32:21 -0800374 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
375 if (eTDLS_LINK_CONNECTED != curr_peer->link_status) {
376 if (curr_peer->tx_pkt >=
377 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800378
379 if (++curr_peer->discovery_attempt <
380 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700381 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700382 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam Ng01120412013-02-19 18:32:21 -0800383 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800384 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800385 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800386 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800387 curr_peer->link_status = eTDLS_LINK_IDLE;
388 }
Chilam Ng01120412013-02-19 18:32:21 -0800389 }
390 }
Chilam NG571c65a2013-01-19 12:27:36 +0530391 }
392
Hoonki Leecdd8e962013-01-20 00:45:46 -0800393next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530394 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800395 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800396 }
Chilam NG571c65a2013-01-19 12:27:36 +0530397 }
398
399 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
400 pHddTdlsCtx->threshold_config.tx_period_t );
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800401 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530402}
403
Chilam Ng1279e232013-01-25 15:06:52 -0800404static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
405{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800406#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800407 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
408
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800409 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800410 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " trigger teardown",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800411 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800412 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800413 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800414 {
415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
416 "%s: unable to lock list", __func__);
417 return;
418 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800419
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800420 cfg80211_tdls_oper_request(curr_peer->pHddTdlsCtx->pAdapter->dev,
Chilam Ng1279e232013-01-25 15:06:52 -0800421 curr_peer->peerMac,
Hoonki Leea34dd892013-02-05 22:56:02 -0800422 NL80211_TDLS_TEARDOWN,
423 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
Chilam Ng1279e232013-01-25 15:06:52 -0800424 GFP_KERNEL);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800425 mutex_unlock(&tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800426#endif
427}
428
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700429static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
430{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700431 int i;
432 struct list_head *head;
433 hddTdlsPeer_t *tmp;
434 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700435 tdlsCtx_t *pHddTdlsCtx;
436
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700437 if (mutex_lock_interruptible(&tdls_lock))
438 {
439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
440 "%s: unable to lock list", __func__);
441 return ;
442 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700443 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700444
445 if ( NULL == pHddTdlsCtx )
446 {
447 mutex_unlock(&tdls_lock);
448 return ;
449 }
450
451 for (i = 0; i < 256; i++) {
452 head = &pHddTdlsCtx->peer_list[i];
453 list_for_each_safe (pos, q, head) {
454 tmp = list_entry(pos, hddTdlsPeer_t, node);
455 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
456 {
457 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
458 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
459 MAC_ADDR_ARRAY(tmp->peerMac));
460 tmp->link_status = eTDLS_LINK_IDLE;
461 }
462 }
463 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700464
465 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700466 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700467
468 mutex_unlock(&tdls_lock);
469
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700470 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
471
472 return;
473}
474
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800475static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800476{
477 int i;
478 struct list_head *head;
479 hddTdlsPeer_t *tmp;
480 struct list_head *pos, *q;
481
482 if (NULL == pHddTdlsCtx) return;
483
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800484
485 for (i = 0; i < 256; i++) {
486 head = &pHddTdlsCtx->peer_list[i];
487 list_for_each_safe (pos, q, head) {
488 tmp = list_entry(pos, hddTdlsPeer_t, node);
489 list_del(pos);
490 vos_mem_free(tmp);
491 }
492 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800493}
494
Hoonki Lee27511902013-03-14 18:19:06 -0700495int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800496{
Chilam Ng01120412013-02-19 18:32:21 -0800497 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700498 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800499 int i;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800500 v_U8_t staIdx;
Chilam Ng01120412013-02-19 18:32:21 -0800501
Hoonki Lee27511902013-03-14 18:19:06 -0700502 mutex_init(&tdls_lock);
Chilam Ng01120412013-02-19 18:32:21 -0800503
Hoonki Lee27511902013-03-14 18:19:06 -0700504 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
505 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
506 {
507 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
508 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
509 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
510 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
511 sme_IsFeatureSupportedByFW(TDLS));
512 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800513 }
514
Hoonki Lee27511902013-03-14 18:19:06 -0700515 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
516
517 if (NULL == pHddTdlsCtx) {
518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
519 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
520 return -1;
521 }
522
523 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
524
525 /* initialize TDLS global context */
526 pHddCtx->connected_peer_count = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700527 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700528
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700529 pHddCtx->tdls_scan_ctxt.magic = 0;
530 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
531
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800532 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
533 {
534 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
535 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
536 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
537 sizeof(v_MACADDR_t)) ;
Chilam Ng01120412013-02-19 18:32:21 -0800538 }
539
Hoonki Lee27511902013-03-14 18:19:06 -0700540 /* initialize TDLS pAdater context */
541 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
542
543 pHddTdlsCtx->pAdapter = pAdapter;
544
545 for (i = 0; i < 256; i++)
546 {
547 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
548 }
549
Chilam Ng01120412013-02-19 18:32:21 -0800550 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
551 VOS_TIMER_TYPE_SW,
552 wlan_hdd_tdls_discover_peer_cb,
553 pHddTdlsCtx);
554
555 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
556 VOS_TIMER_TYPE_SW,
557 wlan_hdd_tdls_update_peer_cb,
558 pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700559 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
560 VOS_TIMER_TYPE_SW,
561 wlan_hdd_tdls_discovery_timeout_peer_cb,
562 pHddTdlsCtx);
Chilam Ng01120412013-02-19 18:32:21 -0800563
Hoonki Lee27511902013-03-14 18:19:06 -0700564 /* remember configuration even if it is not used right now. it could be used later */
565 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
566 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
567 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
568 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
569 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
570 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
571 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
572 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
573 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530574
Chilam Ng01120412013-02-19 18:32:21 -0800575 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
Hoonki Lee387663d2013-02-05 18:08:43 -0800576 {
Chilam Ng01120412013-02-19 18:32:21 -0800577 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
Hoonki Leebf870f32013-01-19 15:53:30 +0530578 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Leebf870f32013-01-19 15:53:30 +0530579 }
Hoonki Lee27511902013-03-14 18:19:06 -0700580 else
581 {
582 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700583#ifdef FEATURE_WLAN_TDLS_INTERNAL
Hoonki Lee27511902013-03-14 18:19:06 -0700584 vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
585 pHddTdlsCtx->threshold_config.discovery_period_t );
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700586#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530587
Hoonki Lee27511902013-03-14 18:19:06 -0700588 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
589 pHddTdlsCtx->threshold_config.tx_period_t );
590 }
591
592 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530593}
594
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800595void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530596{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800597 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700598 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800599
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800600 if (mutex_lock_interruptible(&tdls_lock))
601 {
602 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
603 "%s: unable to lock list", __func__);
604 return;
605 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800606
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700607 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
608 if (NULL == pHddCtx)
609 {
610 mutex_unlock(&tdls_lock);
611 return;
612 }
613
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800614 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800615 if (NULL == pHddTdlsCtx)
616 {
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800617 mutex_unlock(&tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800618 hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
619 return;
620 }
621
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800622 /* must stop timer here before freeing peer list, because peerIdleTimer is
623 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800624 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
625 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800626
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700627 pHddCtx->tdls_scan_ctxt.magic = 0;
628 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
629
Chilam Nga75d8b62013-01-29 01:35:59 -0800630 vos_mem_free(pHddTdlsCtx);
631 pHddTdlsCtx = NULL;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800632 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530633}
634
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800635/* stop all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800636static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800637{
638 int i;
639 struct list_head *head;
640 struct list_head *pos;
641 hddTdlsPeer_t *curr_peer;
642
643 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
644 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700645 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800646
647 for (i = 0; i < 256; i++)
648 {
649 head = &pHddTdlsCtx->peer_list[i];
650
651 list_for_each (pos, head) {
652 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
653
654 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800655 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800656 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800657 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800658 vos_timer_stop ( &curr_peer->peerIdleTimer );
659 }
660 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800661}
662
663/* destroy all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800664static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800665{
666 int i;
667 struct list_head *head;
668 struct list_head *pos;
669 hddTdlsPeer_t *curr_peer;
670
671 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
672 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
673 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
674 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700675 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
676 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800677
678 for (i = 0; i < 256; i++)
679 {
680 head = &pHddTdlsCtx->peer_list[i];
681
682 list_for_each (pos, head) {
683 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
684
685 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800686 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800687 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800688 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800689 vos_timer_stop ( &curr_peer->peerIdleTimer );
690 vos_timer_destroy ( &curr_peer->peerIdleTimer );
691 }
692 }
693}
694
Hoonki Lee387663d2013-02-05 18:08:43 -0800695/* if mac address exist, return pointer
696 if mac address doesn't exist, create a list and add, return pointer
697 return NULL if fails to get new mac address
698*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800699hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530700{
Hoonki Lee387663d2013-02-05 18:08:43 -0800701 struct list_head *head;
702 hddTdlsPeer_t *peer;
703 u8 key;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800704 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530705
Hoonki Lee387663d2013-02-05 18:08:43 -0800706 if (NULL == pHddTdlsCtx)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800707 {
708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
709 "%s: pHddTdlsCtx is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800710 return NULL;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800711 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800712
Hoonki Lee387663d2013-02-05 18:08:43 -0800713 /* if already there, just update */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800714 peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800715 if (peer != NULL)
716 {
717 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530718 }
719
Hoonki Lee387663d2013-02-05 18:08:43 -0800720 /* not found, allocate and add the list */
721 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
722 if (NULL == peer) {
723 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
724 return NULL;
725 }
Chilam NG571c65a2013-01-19 12:27:36 +0530726
Hoonki Lee387663d2013-02-05 18:08:43 -0800727 key = wlan_hdd_tdls_hash_key(mac);
728 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530729
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800730 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -0800731 {
732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
733 "%s: unable to lock list", __func__);
734 return NULL;
735 }
Chilam NG571c65a2013-01-19 12:27:36 +0530736
Hoonki Lee387663d2013-02-05 18:08:43 -0800737 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
738 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800739 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800740
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800741 vos_timer_init(&peer->peerIdleTimer,
742 VOS_TIMER_TYPE_SW,
743 wlan_hdd_tdls_idle_cb,
744 peer);
745
Hoonki Lee387663d2013-02-05 18:08:43 -0800746 list_add_tail(&peer->node, head);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800747 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800748
749 return peer;
750}
751
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700752int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -0700753 u8* mac,
754 tTDLSCapType cap)
755{
756 hddTdlsPeer_t *curr_peer;
757
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700758 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -0700759 if (curr_peer == NULL)
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700760 return -1;
Hoonki Lee27511902013-03-14 18:19:06 -0700761
762 curr_peer->tdls_support = cap;
763
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700764 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -0700765}
766
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800767void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800768{
769 if (curr_peer == NULL)
770 return;
771
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800772 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800773 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530774
775 curr_peer->link_status = status;
776
Chilam NG571c65a2013-01-19 12:27:36 +0530777}
778
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800779void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
780 u8* mac,
781 tTDLSLinkStatus linkStatus)
782{
783 hddTdlsPeer_t *curr_peer;
784
785 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
786 if (curr_peer == NULL)
787 return;
788
789 curr_peer->link_status= linkStatus;
790
791 return;
792}
793
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800794int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530795{
796 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700797 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530798
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800799 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700800
801 if (NULL == curr_peer)
Hoonki Lee387663d2013-02-05 18:08:43 -0800802 return -1;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700803
804 if (pHddTdlsCtx->discovery_sent_cnt)
805 pHddTdlsCtx->discovery_sent_cnt--;
806
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700807 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700808 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700809 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700810 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700811 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700812
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800813 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700814 "Discovery(%lu) Response from " MAC_ADDRESS_STR " link_status %d",
815 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
816 curr_peer->link_status);
817
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800818 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800819 {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700820 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
821
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700822 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
823 "Indicating Set-Up to supplicant");
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800824 cfg80211_tdls_oper_request(pAdapter->dev,
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800825 curr_peer->peerMac,
826 NL80211_TDLS_SETUP, FALSE,
827 GFP_KERNEL);
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800828 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700829 else
830 {
831 wlan_hdd_tdls_check_bmps(pAdapter);
832 }
Chilam NG571c65a2013-01-19 12:27:36 +0530833
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800834 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -0800835 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530836}
837
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800838int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +0530839{
840 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530841
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800842 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800843 if (curr_peer == NULL)
844 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530845
846 curr_peer->rssi = rxRssi;
847
Hoonki Lee387663d2013-02-05 18:08:43 -0800848 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530849}
850
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800851int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -0800852{
853 hddTdlsPeer_t *curr_peer;
854
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800855 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800856 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800857 return -1;
858
859 curr_peer->is_responder = responder;
860
861 return 0;
862}
863
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800864int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -0800865{
866 hddTdlsPeer_t *curr_peer;
867
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800868 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800869 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800870 return -1;
871
872 return (curr_peer->is_responder);
873}
874
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800875int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800876{
877 hddTdlsPeer_t *curr_peer;
878
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800879 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800880 if (curr_peer == NULL)
881 return -1;
882
883 curr_peer->signature = uSignature;
884
885 return 0;
886}
887
Hoonki Leea34dd892013-02-05 22:56:02 -0800888
Hoonki Lee387663d2013-02-05 18:08:43 -0800889void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530890{
Chilam NG571c65a2013-01-19 12:27:36 +0530891 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +0530892}
893
Hoonki Lee387663d2013-02-05 18:08:43 -0800894void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -0800895{
Chilam Ng1279e232013-01-25 15:06:52 -0800896 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -0800897}
898
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800899int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +0530900{
Hoonki Lee387663d2013-02-05 18:08:43 -0800901 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800902 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530903
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800904 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
905 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -0800906
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800907 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800908 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +0530909 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530910
Chilam Ng1279e232013-01-25 15:06:52 -0800911 if (tx)
912 curr_peer->tx_pkt++;
913 else
914 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +0530915
Chilam NG571c65a2013-01-19 12:27:36 +0530916 return 0;
917}
918
Hoonki Lee27511902013-03-14 18:19:06 -0700919static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
920{
921 if (config->tdls > 2)
922 {
923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
924 return -1;
925 }
926 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
927 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
928 {
929 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%d>", __func__, config->tx_period_t,
930 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
931 return -1;
932 }
933 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
934 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
935 {
936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%d>", __func__, config->tx_packet_n,
937 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
938 return -1;
939 }
940 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
941 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
942 {
943 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%d>", __func__, config->discovery_period_t,
944 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
945 return -1;
946 }
947 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
948 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
949 {
950 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
951 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
952 return -1;
953 }
954 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
955 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
956 {
957 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
958 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
959 return -1;
960 }
961 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
962 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
963 {
964 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
965 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
966 return -1;
967 }
968 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
969 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
970 {
971 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
972 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
973 return -1;
974 }
975 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
976 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
977 {
978 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
979 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
980 return -1;
981 }
982 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
983 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
984 {
985 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
986 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
987 return -1;
988 }
989 return 0;
990}
991
Chilam Ng01120412013-02-19 18:32:21 -0800992int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +0530993{
Chilam Ng01120412013-02-19 18:32:21 -0800994 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
995 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800996 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -0700997 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -0800998
Hoonki Lee27511902013-03-14 18:19:06 -0700999 if (NULL == pHddTdlsCtx)
1000 {
1001 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
1002 return -1;
Chilam Ng01120412013-02-19 18:32:21 -08001003 }
Chilam NG571c65a2013-01-19 12:27:36 +05301004
Hoonki Lee27511902013-03-14 18:19:06 -07001005 if (wlan_hdd_tdls_check_config(config) != 0)
1006 {
1007 return -1;
1008 }
1009
1010 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1011 req_tdls_mode = config->tdls + 1;
1012 if (pHddCtx->tdls_mode == req_tdls_mode)
1013 {
1014 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1015 return -1;
1016 }
1017
1018 /* copy the configuration only when given tdls mode is implicit trigger enable */
1019 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1020 {
Chilam Ng01120412013-02-19 18:32:21 -08001021 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1022 }
Chilam NG571c65a2013-01-19 12:27:36 +05301023
Chilam Ng01120412013-02-19 18:32:21 -08001024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1025 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1026 config->tdls,
1027 config->tx_period_t,
1028 config->tx_packet_n,
1029 config->discovery_period_t,
1030 config->discovery_tries_n,
1031 config->idle_timeout_t,
1032 config->idle_packet_n,
1033 config->rssi_hysteresis,
1034 config->rssi_trigger_threshold,
1035 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301036
Hoonki Lee27511902013-03-14 18:19:06 -07001037 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode);
Chilam Ng01120412013-02-19 18:32:21 -08001038
Chilam NG571c65a2013-01-19 12:27:36 +05301039 return 0;
1040}
1041
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001042int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001043{
Hoonki Lee387663d2013-02-05 18:08:43 -08001044 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001045
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001046 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001047 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +05301048 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301049
Hoonki Lee387663d2013-02-05 18:08:43 -08001050 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301051
1052 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001053}
1054
Hoonki Lee387663d2013-02-05 18:08:43 -08001055/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1056 otherwise, it returns NULL
1057*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001058hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac)
Kiran V1ccee932012-12-12 14:49:46 -08001059{
Hoonki Lee387663d2013-02-05 18:08:43 -08001060 u8 key;
1061 struct list_head *pos;
1062 struct list_head *head;
1063 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001064 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -08001065
Hoonki Lee387663d2013-02-05 18:08:43 -08001066
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001067 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -08001068 {
1069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1070 "%s: unable to lock list", __func__);
1071 return NULL;
1072 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001073 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001074 if (NULL == pHddTdlsCtx)
1075 {
1076 mutex_unlock(&tdls_lock);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001077 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1078 "%s: pHddTdlsCtx is NULL", __func__);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001079 return NULL;
1080 }
1081
1082 key = wlan_hdd_tdls_hash_key(mac);
1083
1084 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001085
1086 list_for_each(pos, head) {
1087 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1088 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1089 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1090 "findTdlsPeer: found staId %d", curr_peer->staId);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001091 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001092 return curr_peer;
1093 }
1094 }
1095
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001096 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001097 return NULL;
1098}
1099
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001100int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001101{
Chilam Ng01120412013-02-19 18:32:21 -08001102 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301103 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001104
Chilam Ng01120412013-02-19 18:32:21 -08001105 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1106
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001107 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001108 if (curr_peer == NULL)
1109 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301110
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001111 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001112 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001113
Chilam Ng01120412013-02-19 18:32:21 -08001114 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001115 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001116 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001117 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001118}
1119
Hoonki Lee27511902013-03-14 18:19:06 -07001120static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1121{
1122 int i;
1123 struct list_head *head;
1124 hddTdlsPeer_t *tmp;
1125 struct list_head *pos, *q;
1126
1127 if (mutex_lock_interruptible(&tdls_lock))
1128 {
1129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1130 "%s: unable to lock list", __func__);
1131 return ;
1132 }
1133 if ( NULL == pHddTdlsCtx )
1134 {
1135 mutex_unlock(&tdls_lock);
1136 return ;
1137 }
1138
1139 for (i = 0; i < 256; i++) {
1140 head = &pHddTdlsCtx->peer_list[i];
1141 list_for_each_safe (pos, q, head) {
1142 tmp = list_entry(pos, hddTdlsPeer_t, node);
1143 tmp->tx_pkt = 0;
1144 tmp->rx_pkt = 0;
1145 }
1146 }
1147 mutex_unlock(&tdls_lock);
1148
1149 return ;
1150}
1151
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001152static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001153{
1154 int i;
1155 struct list_head *head;
1156 hddTdlsPeer_t *tmp;
1157 struct list_head *pos, *q;
1158
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001159 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001160 {
1161 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1162 "%s: unable to lock list", __func__);
1163 return -1;
1164 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001165 if ( NULL == pHddTdlsCtx )
1166 {
1167 mutex_unlock(&tdls_lock);
1168 return -1;
1169 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001170
1171 pHddTdlsCtx->discovery_peer_cnt = 0;
1172
1173 for (i = 0; i < 256; i++) {
1174 head = &pHddTdlsCtx->peer_list[i];
1175 list_for_each_safe (pos, q, head) {
1176 tmp = list_entry(pos, hddTdlsPeer_t, node);
1177 tmp->discovery_processed = 0;
1178 }
1179 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001180 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001181
1182 return 0;
1183}
1184
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001185static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001186{
1187 int i;
1188 struct list_head *head;
1189 struct list_head *pos, *q;
1190 int discovery_peer_cnt=0;
1191 hddTdlsPeer_t *tmp;
1192
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001193 /*
1194 * This function expects the callers to acquire the Mutex.
1195 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001196
1197 for (i = 0; i < 256; i++) {
1198 head = &pHddTdlsCtx->peer_list[i];
1199 list_for_each_safe (pos, q, head) {
1200 tmp = list_entry(pos, hddTdlsPeer_t, node);
1201 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001202 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1203 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001204 discovery_peer_cnt++;
1205 }
1206 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001207 return discovery_peer_cnt;
1208}
1209
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001210tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001211{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001212 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1213
1214 if (NULL == pHddCtx)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001215 return 0;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001216
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001217 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001218}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001219
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001220int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001221{
1222 int i;
1223 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001224 struct list_head *head;
1225 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001226 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001227 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001228
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001229
1230 init_len = buflen;
1231 len = snprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", "MAC", "Id", "cap", "up", "RSSI");
1232 buf += len;
1233 buflen -= len;
1234 /* 1234567890123456789012345678901234567 */
1235 len = snprintf(buf, buflen, "---------------------------------\n");
1236 buf += len;
1237 buflen -= len;
1238
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001239 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001240 {
1241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1242 "%s: unable to lock list", __func__);
1243 return init_len-buflen;
1244 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001245 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001246 if (NULL == pHddTdlsCtx) {
1247 mutex_unlock(&tdls_lock);
1248 len = snprintf(buf, buflen, "TDLS not enabled\n");
1249 return len;
1250 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001251 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001252 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001253
Hoonki Lee387663d2013-02-05 18:08:43 -08001254 list_for_each(pos, head) {
1255 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001256
Hoonki Lee387663d2013-02-05 18:08:43 -08001257 if (buflen < 32+1)
1258 break;
1259 len = snprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001260 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1261 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001262 curr_peer->staId,
1263 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
1264 (curr_peer->link_status == eTDLS_LINK_CONNECTED) ? "Y":"N",
1265 curr_peer->rssi);
1266 buf += len;
1267 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001268 }
1269 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001270 mutex_unlock(&tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001271 return init_len-buflen;
1272}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001273
1274void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1275{
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001276 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001277 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001278
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001279 if (NULL == pHddTdlsCtx) return;
1280
1281 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1282 "%s, update %d discover %d", __func__,
1283 pHddTdlsCtx->threshold_config.tx_period_t,
1284 pHddTdlsCtx->threshold_config.discovery_period_t);
1285
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001286 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1287 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001288 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001289 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001290 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001291
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001292#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001293 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer,
1294 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001295#endif
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001296 vos_timer_start(&pHddTdlsCtx->peerUpdateTimer,
1297 pHddTdlsCtx->threshold_config.tx_period_t);
1298 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001299
1300}
1301
1302void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1303{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001304 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001305
1306 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1307
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001308 if (mutex_lock_interruptible(&tdls_lock))
1309 {
1310 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1311 "%s: unable to lock list", __func__);
1312 return;
1313 }
1314 if (NULL == pHddTdlsCtx)
1315 {
1316 mutex_unlock(&tdls_lock);
1317 return;
1318 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001319 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001320 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001321
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001322 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
1323 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001324
1325 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001326}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001327
1328void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1329{
1330 pAdapter->mgmtTxCompletionStatus = statusCode;
1331 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1332 __func__, statusCode);
1333 complete(&pAdapter->tdls_mgmt_comp);
1334}
1335
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001336void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001337{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001338 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001339
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001340 if (NULL == pHddCtx) return;
1341
1342 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001343 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001344
1345 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1346 __func__, pHddCtx->connected_peer_count);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001347}
1348
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001349void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001350{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001351 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001352
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001353 if (NULL == pHddCtx) return;
1354
1355 if (pHddCtx->connected_peer_count)
1356 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001357 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001358
1359 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1360 __func__, pHddCtx->connected_peer_count);
1361
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001362}
1363
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001364void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001365{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001366 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001367 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001368
Gopichand Nakkala16c02842013-03-18 12:31:35 -07001369 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001370
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001371 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
1372 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001373 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001374 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001375 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1376 {
1377 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001378 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1379 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001380 hdd_enable_bmps_imps(pHddCtx);
1381 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001382 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001383 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001384 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001385 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1386 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001387 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1388 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001389 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1390 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001391 }
1392 return;
1393}
1394
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001395u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
1396{
1397 hddTdlsPeer_t *curr_peer;
1398
1399 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
1400 if (curr_peer == NULL)
1401 return 0;
1402
1403 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
1404}
1405
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001406/* return TRUE if TDLS is ongoing
1407 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1408 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1409 mac is NULL, this argument is ignored, and check for all the peer list.
1410 */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001411u8 wlan_hdd_tdls_is_progress(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001412{
1413 int i;
1414 struct list_head *head;
1415 hddTdlsPeer_t *curr_peer;
1416 struct list_head *pos;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001417 tdlsCtx_t *pHddTdlsCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001418
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001419 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001420 {
1421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1422 "%s: unable to lock list", __func__);
1423 return FALSE;
1424 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001425 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001426 if (NULL == pHddTdlsCtx)
1427 {
1428 mutex_unlock(&tdls_lock);
1429 return FALSE;
1430 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001431
1432 for (i = 0; i < 256; i++) {
1433 head = &pHddTdlsCtx->peer_list[i];
1434 list_for_each(pos, head) {
1435 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1436 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1437 continue;
1438 }
1439 else
1440 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001441 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001442 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001443 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001444 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001445 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001446 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001447 return TRUE;
1448 }
1449 }
1450 }
1451 }
1452
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001453 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001454 return FALSE;
1455}
Hoonki Lee27511902013-03-14 18:19:06 -07001456
1457static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1458{
1459 if (mutex_lock_interruptible(&tdls_lock))
1460 {
1461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1462 "%s: unable to lock list", __func__);
1463 return;
1464 }
1465
1466 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
1467
1468 mutex_unlock(&tdls_lock);
1469}
1470
1471static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1472{
1473 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001474 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001475 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001476 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001477
Hoonki Lee27511902013-03-14 18:19:06 -07001478
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001479#ifdef FEATURE_WLAN_TDLS_INTERNAL
Hoonki Lee27511902013-03-14 18:19:06 -07001480 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer,
1481 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001482#endif
Hoonki Lee27511902013-03-14 18:19:06 -07001483
1484 vos_timer_start(&pHddTdlsCtx->peerUpdateTimer,
1485 pHddTdlsCtx->threshold_config.tx_period_t);
1486}
1487
1488void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, eTDLSSupportMode tdls_mode)
1489{
1490 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1491 VOS_STATUS status;
1492 hdd_adapter_t *pAdapter;
1493 tdlsCtx_t *pHddTdlsCtx;
1494
1495 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
1496
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001497 if (NULL == pHddCtx) return;
1498
1499 if (pHddCtx->tdls_mode == tdls_mode)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, (int)tdls_mode);
1502 return;
1503 }
1504
Hoonki Lee27511902013-03-14 18:19:06 -07001505 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1506
1507 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1508 {
1509 pAdapter = pAdapterNode->pAdapter;
1510 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1511 if (NULL != pHddTdlsCtx)
1512 {
1513 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
1514 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
1515 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
1516 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
1517 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
1518 }
1519 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1520 pAdapterNode = pNext;
1521 }
1522 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
1523 pHddCtx->tdls_mode = tdls_mode;
1524}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001525
1526void wlan_hdd_tdls_pre_setup(tdlsCtx_t *pHddTdlsCtx,
1527 hddTdlsPeer_t *curr_peer)
1528{
1529 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1530
1531 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
1532 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001533 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001534 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1535 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001536
1537 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
1538 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
1539
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001540 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
1541 pHddTdlsCtx->pAdapter->sessionId,
1542 curr_peer->peerMac,
1543 WLAN_TDLS_DISCOVERY_REQUEST,
1544 1, 0, NULL, 0, 0);
1545 pHddTdlsCtx->discovery_sent_cnt++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001546 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001547 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %lu timeout %lu msec",
1548 __func__, pHddTdlsCtx->discovery_sent_cnt,
1549 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001550 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001551 vos_timer_start(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
1552 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001553
1554 return;
1555}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001556
1557tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
1558{
1559 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1560 hdd_adapter_t *pAdapter = NULL;
1561 tdlsCtx_t *pHddTdlsCtx = NULL;
1562 VOS_STATUS status = 0;
1563 tANI_U32 count = 0;
1564
1565 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1566 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1567 {
1568 pAdapter = pAdapterNode->pAdapter;
1569
1570 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1571 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
1572 {
1573 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1574 if (NULL != pHddTdlsCtx)
1575 {
1576 count = count + pHddTdlsCtx->discovery_sent_cnt;
1577 }
1578 }
1579 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1580 pAdapterNode = pNext;
1581 }
1582 return count;
1583}
1584
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001585void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001586{
1587 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1588 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1589
1590 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
1591 return;
1592
1593 if ((0 == pHddCtx->connected_peer_count) &&
1594 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
1595 {
1596 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
1597 return;
1598 }
1599 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
1600 return;
1601}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001602
1603void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
1604{
1605 if (NULL == tdls_scan_ctx)
1606 return;
1607
1608 tdls_scan_ctx->scan_request = NULL;
1609 return;
1610}
1611
1612int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
1613 struct wiphy *wiphy,
1614#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1615 struct net_device *dev,
1616#endif
1617 struct cfg80211_scan_request *request)
1618{
1619 tdls_scan_context_t *scan_ctx;
1620
1621 if (NULL == pHddCtx )
1622 return -1;
1623
1624 scan_ctx = &pHddCtx->tdls_scan_ctxt;
1625
1626 scan_ctx->wiphy = wiphy;
1627#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1628 scan_ctx->dev = dev;
1629#endif
1630
1631 scan_ctx->scan_request = request;
1632 return 0;
1633}
1634
1635static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
1636{
1637 tdls_scan_context_t *scan_ctx =
1638 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
1639
1640 if (NULL == scan_ctx)
1641 return;
1642
1643 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
1644 return;
1645
1646 scan_ctx->attempt++;
1647
1648 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
1649#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1650 scan_ctx->dev,
1651#endif
1652 scan_ctx->scan_request);
1653}
1654
1655static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
1656 struct wiphy *wiphy,
1657#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1658 struct net_device *dev,
1659#endif
1660 struct cfg80211_scan_request *request,
1661 unsigned long delay)
1662{
1663 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
1664 {
1665#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1666 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
1667#else
1668 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
1669#endif
1670 pHddCtx->tdls_scan_ctxt.attempt = 0;
1671 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
1672 }
1673 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
1674
1675 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
1676}
1677
1678/* return negative = caller should stop and return error code immediately
1679 return 0 = caller should stop and return success immediately
1680 return 1 = caller can continue to scan
1681 */
1682int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
1683 struct wiphy *wiphy,
1684#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1685 struct net_device *dev,
1686#endif
1687 struct cfg80211_scan_request *request)
1688{
1689#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1690 struct net_device *dev = request->wdev->netdev;
1691#endif
1692 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1693 u16 connectedTdlsPeers;
1694 unsigned long delay;
1695
1696 if (NULL == pHddCtx)
1697 return 0;
1698
1699 /* if tdls is not enabled, then continue scan */
1700 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
1701 return 1;
1702
1703 if (wlan_hdd_tdls_is_progress(pAdapter, NULL, 0))
1704 {
1705 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1706 "%s: tdls in progress. scan rejected",
1707 __func__);
1708 return -EBUSY;
1709 }
1710
1711 /* tdls teardown is ongoing */
1712 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
1713 {
1714 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
1715 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
1716 {
1717 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
1718 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1719 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
1720 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
1721
1722 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
1723#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1724 dev,
1725#endif
1726 request,
1727 msecs_to_jiffies(delay));
1728 /* scan should not continue */
1729 return 0;
1730 }
1731 /* no connected peer or max retry reached, scan continue */
1732 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1733 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
1734 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
1735 return 1;
1736 }
1737 /* while tdls is up, first time scan */
1738 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
1739 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
1740 {
1741 /* disable implicit trigger logic & tdls operatoin */
1742 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED);
1743 /* indicate the teardown all connected to peer */
1744 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
1745 if (connectedTdlsPeers)
1746 {
1747 tANI_U8 staIdx;
1748
1749 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
1750 {
1751 if (pHddCtx->tdlsConnInfo[staIdx].staId)
1752 {
1753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1754 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
1755
1756#ifdef CONFIG_TDLS_IMPLICIT
1757 cfg80211_tdls_oper_request(pAdapter->dev,
1758 pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes,
1759 NL80211_TDLS_TEARDOWN,
1760 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
1761 GFP_KERNEL);
1762#endif
1763 }
1764 }
1765 /* schedule scan */
1766 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
1767
1768 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1769 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
1770 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
1771 delay);
1772
1773 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
1774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1775 dev,
1776#endif
1777 request,
1778 msecs_to_jiffies(delay));
1779 /* scan should not continue */
1780 return 0;
1781 }
1782 /* no connected peer, scan continue */
1783 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1784 "%s: tdls_mode %d, and no tdls connection. scan allowed",
1785 __func__, pHddCtx->tdls_mode);
1786 }
1787 return 1;
1788}
1789
1790void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
1791{
1792 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1793 tdls_scan_context_t *scan_ctx;
1794
1795 if (NULL == pHddCtx)
1796 return;
1797
1798 /* free allocated memory at scan time */
1799 scan_ctx = &pHddCtx->tdls_scan_ctxt;
1800 wlan_hdd_tdls_free_scan_request (scan_ctx);
1801 scan_ctx->attempt = 0;
1802 scan_ctx->magic = 0;
1803
1804 /* if tdls was enabled before scan, re-enable tdls mode */
1805 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
1806 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
1807 {
1808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1809 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
1810
1811 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last);
1812 }
1813 wlan_hdd_tdls_check_bmps(pAdapter);
1814}