blob: 676666abd162eddab676f5a60a8f9461f658c56b [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 Nakkala75e7b282013-03-15 18:37:13 -070094#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -070095 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
96 &pHddTdlsCtx->peerDiscoverTimer,
97 discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -070098#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -070099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
100 pHddTdlsCtx->ap_rssi);
101
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800102 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) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800176 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
177 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800178 curr_peer->peerMac,
179 WLAN_TDLS_DISCOVERY_REQUEST,
180 1, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800181 curr_peer->discovery_attempt++;
182 }
183 else
184 {
185 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
186 "%s: Maximum Discovery retries reached", __func__);
187 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
188 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800189
190 }
191 }
Chilam NG571c65a2013-01-19 12:27:36 +0530192 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800193 else
194 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800195 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800196 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800197exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800198
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800199 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
200 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
201 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
202 pHddTdlsCtx->discovery_peer_cnt);
203 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800204 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800205 goto done;
206 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800207 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
208
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800209 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530210
Gopichand Nakkala638ebc72013-03-21 18:04:02 -0700211 mutex_unlock(&tdls_lock);
212
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800213 /* Commenting out the following function as it was introducing
214 * a race condition when pHddTdlsCtx is deleted. Also , this
215 * function is consuming more time in the timer callback.
216 * RSSI based trigger needs to revisit this part of the code.
217 */
218
219 /*
220 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
221 */
Chilam NG571c65a2013-01-19 12:27:36 +0530222
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800223done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800224 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800225
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800226 if ( !doMutexLock )
227 mutex_unlock(&tdls_lock);
228 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800229}
Chilam NG571c65a2013-01-19 12:27:36 +0530230
Hoonki Lee387663d2013-02-05 18:08:43 -0800231static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530232{
233 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800234 struct list_head *head;
235 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530236 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800237 tdlsCtx_t *pHddTdlsCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800238
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800239 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800240 {
241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
242 "%s: unable to lock list", __func__);
243 return;
244 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800245 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800246 if (NULL == pHddTdlsCtx)
247 {
248 mutex_unlock(&tdls_lock);
249 return;
250 }
251
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800252 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800253 {
254 mutex_unlock(&tdls_lock);
255 return;
256 }
257
Chilam NG571c65a2013-01-19 12:27:36 +0530258 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800259 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530260
Hoonki Lee387663d2013-02-05 18:08:43 -0800261 list_for_each (pos, head) {
262 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530263
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800264 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700265 "hdd update cb " MAC_ADDRESS_STR " link_status %d"
266 " tdls_support %d", MAC_ADDR_ARRAY(curr_peer->peerMac),
267 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800268
Chilam NG571c65a2013-01-19 12:27:36 +0530269 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800270 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800271 "%s: (tx %d, rx %d, config %d) " MAC_ADDRESS_STR " (%d) ",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800272 __func__, curr_peer->tx_pkt, curr_peer->rx_pkt,
273 pHddTdlsCtx->threshold_config.tx_packet_n,
Chilam Ng01120412013-02-19 18:32:21 -0800274 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->link_status);
275
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800276 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
277 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Chilam NG571c65a2013-01-19 12:27:36 +0530278 if (curr_peer->tx_pkt >=
279 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800280
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800281 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800282 {
283
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700284 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530285#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700286 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530287#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800288 }
289 else
290 {
291 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800292 "%s: Maximum peer connected already! %d",
293 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800294 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800295 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530296 }
Chilam NG571c65a2013-01-19 12:27:36 +0530297 } else {
Chilam Ng01120412013-02-19 18:32:21 -0800298 if ((tANI_S32)curr_peer->rssi <
299 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800300
Chilam Ng01120412013-02-19 18:32:21 -0800301 VOS_TRACE( VOS_MODULE_ID_HDD,
302 VOS_TRACE_LEVEL_WARN,
303 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
304 MAC_ADDR_ARRAY(curr_peer->peerMac));
305#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700306 wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
307 curr_peer,
308 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Chilam Ng01120412013-02-19 18:32:21 -0800309#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800310 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530311 }
Chilam Ng01120412013-02-19 18:32:21 -0800312
313 if ((curr_peer->tx_pkt <
314 pHddTdlsCtx->threshold_config.idle_packet_n) &&
315 (curr_peer->rx_pkt <
316 pHddTdlsCtx->threshold_config.idle_packet_n)) {
317 if (VOS_TIMER_STATE_RUNNING !=
318 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
320 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
321 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700322 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
323 &curr_peer->peerIdleTimer,
324 pHddTdlsCtx->threshold_config.idle_timeout_t);
Chilam Ng01120412013-02-19 18:32:21 -0800325 }
326 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800327 if (VOS_TIMER_STATE_RUNNING ==
328 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
330 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
331 MAC_ADDR_ARRAY(curr_peer->peerMac));
332 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800333 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800334 }
Chilam Ng01120412013-02-19 18:32:21 -0800335
Hoonki Leecdd8e962013-01-20 00:45:46 -0800336// if (curr_peer->rssi <
337// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
338// pHddTdlsCtx->ap_rssi)) {
339//
340//#ifdef CONFIG_TDLS_IMPLICIT
341// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
342// curr_peer->peerMac,
343// NL80211_TDLS_TEARDOWN, FALSE,
344// GFP_KERNEL);
345//#endif
346// }
Chilam NG571c65a2013-01-19 12:27:36 +0530347 }
Chilam Ng01120412013-02-19 18:32:21 -0800348 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700349 if (!TDLS_IS_CONNECTED(curr_peer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800350 if (curr_peer->tx_pkt >=
351 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800352
Gopichand Nakkala062bcbd2013-03-29 18:14:47 -0700353 if (curr_peer->discovery_attempt++ <
Chilam Ng01120412013-02-19 18:32:21 -0800354 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700355 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700356 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam Ng01120412013-02-19 18:32:21 -0800357 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800358 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800359 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800360 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800361 curr_peer->link_status = eTDLS_LINK_IDLE;
362 }
Chilam Ng01120412013-02-19 18:32:21 -0800363 }
364 }
Chilam NG571c65a2013-01-19 12:27:36 +0530365 }
366
Hoonki Leecdd8e962013-01-20 00:45:46 -0800367next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530368 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800369 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800370 }
Chilam NG571c65a2013-01-19 12:27:36 +0530371 }
372
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700373 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
374 &pHddTdlsCtx->peerUpdateTimer,
375 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800376 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530377}
378
Chilam Ng1279e232013-01-25 15:06:52 -0800379static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
380{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800381#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800382 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
383
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800384 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800385 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " trigger teardown",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800386 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800387 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800388 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800389 {
390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
391 "%s: unable to lock list", __func__);
392 return;
393 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800394
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700395 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
396 curr_peer,
397 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800398 mutex_unlock(&tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800399#endif
400}
401
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700402static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
403{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700404 int i;
405 struct list_head *head;
406 hddTdlsPeer_t *tmp;
407 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700408 tdlsCtx_t *pHddTdlsCtx;
409
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700410 if (mutex_lock_interruptible(&tdls_lock))
411 {
412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
413 "%s: unable to lock list", __func__);
414 return ;
415 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700416 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700417
418 if ( NULL == pHddTdlsCtx )
419 {
420 mutex_unlock(&tdls_lock);
421 return ;
422 }
423
424 for (i = 0; i < 256; i++) {
425 head = &pHddTdlsCtx->peer_list[i];
426 list_for_each_safe (pos, q, head) {
427 tmp = list_entry(pos, hddTdlsPeer_t, node);
428 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
429 {
430 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
431 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
432 MAC_ADDR_ARRAY(tmp->peerMac));
433 tmp->link_status = eTDLS_LINK_IDLE;
434 }
435 }
436 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700437
438 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700439 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700440
441 mutex_unlock(&tdls_lock);
442
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700443 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
444
445 return;
446}
447
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800448static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800449{
450 int i;
451 struct list_head *head;
452 hddTdlsPeer_t *tmp;
453 struct list_head *pos, *q;
454
455 if (NULL == pHddTdlsCtx) return;
456
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800457
458 for (i = 0; i < 256; i++) {
459 head = &pHddTdlsCtx->peer_list[i];
460 list_for_each_safe (pos, q, head) {
461 tmp = list_entry(pos, hddTdlsPeer_t, node);
462 list_del(pos);
463 vos_mem_free(tmp);
464 }
465 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800466}
467
Hoonki Lee27511902013-03-14 18:19:06 -0700468int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800469{
Chilam Ng01120412013-02-19 18:32:21 -0800470 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700471 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800472 int i;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800473 v_U8_t staIdx;
Chilam Ng01120412013-02-19 18:32:21 -0800474
Hoonki Lee27511902013-03-14 18:19:06 -0700475 mutex_init(&tdls_lock);
Chilam Ng01120412013-02-19 18:32:21 -0800476
Hoonki Lee27511902013-03-14 18:19:06 -0700477 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
478 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
479 {
480 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
481 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
483 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
484 sme_IsFeatureSupportedByFW(TDLS));
485 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800486 }
487
Hoonki Lee27511902013-03-14 18:19:06 -0700488 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
489
490 if (NULL == pHddTdlsCtx) {
491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
492 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
493 return -1;
494 }
495
496 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
497
498 /* initialize TDLS global context */
499 pHddCtx->connected_peer_count = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700500 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700501
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700502 pHddCtx->tdls_scan_ctxt.magic = 0;
503 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
504
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800505 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
506 {
507 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
508 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
509 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
510 sizeof(v_MACADDR_t)) ;
Chilam Ng01120412013-02-19 18:32:21 -0800511 }
512
Hoonki Lee27511902013-03-14 18:19:06 -0700513 /* initialize TDLS pAdater context */
514 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
515
516 pHddTdlsCtx->pAdapter = pAdapter;
517
518 for (i = 0; i < 256; i++)
519 {
520 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
521 }
522
Chilam Ng01120412013-02-19 18:32:21 -0800523 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
524 VOS_TIMER_TYPE_SW,
525 wlan_hdd_tdls_discover_peer_cb,
526 pHddTdlsCtx);
527
528 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
529 VOS_TIMER_TYPE_SW,
530 wlan_hdd_tdls_update_peer_cb,
531 pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700532 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
533 VOS_TIMER_TYPE_SW,
534 wlan_hdd_tdls_discovery_timeout_peer_cb,
535 pHddTdlsCtx);
Chilam Ng01120412013-02-19 18:32:21 -0800536
Hoonki Lee27511902013-03-14 18:19:06 -0700537 /* remember configuration even if it is not used right now. it could be used later */
538 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
539 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
540 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
541 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
542 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
543 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
544 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
545 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
546 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530547
Chilam Ng01120412013-02-19 18:32:21 -0800548 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
Hoonki Lee387663d2013-02-05 18:08:43 -0800549 {
Chilam Ng01120412013-02-19 18:32:21 -0800550 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
Hoonki Leebf870f32013-01-19 15:53:30 +0530551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Leebf870f32013-01-19 15:53:30 +0530552 }
Hoonki Lee27511902013-03-14 18:19:06 -0700553 else
554 {
555 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
Hoonki Lee27511902013-03-14 18:19:06 -0700556 }
557
558 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530559}
560
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800561void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530562{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800563 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700564 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800565
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800566 if (mutex_lock_interruptible(&tdls_lock))
567 {
568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
569 "%s: unable to lock list", __func__);
570 return;
571 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800572
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700573 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
574 if (NULL == pHddCtx)
575 {
576 mutex_unlock(&tdls_lock);
577 return;
578 }
579
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800580 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800581 if (NULL == pHddTdlsCtx)
582 {
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800583 mutex_unlock(&tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800584 hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
585 return;
586 }
587
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800588 /* must stop timer here before freeing peer list, because peerIdleTimer is
589 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800590 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
591 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800592
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700593 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
594
Chilam Nga75d8b62013-01-29 01:35:59 -0800595 vos_mem_free(pHddTdlsCtx);
596 pHddTdlsCtx = NULL;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800597 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530598}
599
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800600/* stop all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800601static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800602{
603 int i;
604 struct list_head *head;
605 struct list_head *pos;
606 hddTdlsPeer_t *curr_peer;
607
608 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
609 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700610 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800611
612 for (i = 0; i < 256; i++)
613 {
614 head = &pHddTdlsCtx->peer_list[i];
615
616 list_for_each (pos, head) {
617 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
618
619 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800620 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800621 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800622 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800623 vos_timer_stop ( &curr_peer->peerIdleTimer );
624 }
625 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800626}
627
628/* destroy all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800629static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800630{
631 int i;
632 struct list_head *head;
633 struct list_head *pos;
634 hddTdlsPeer_t *curr_peer;
635
636 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
637 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
638 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
639 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700640 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
641 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800642
643 for (i = 0; i < 256; i++)
644 {
645 head = &pHddTdlsCtx->peer_list[i];
646
647 list_for_each (pos, head) {
648 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
649
650 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800651 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800652 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800653 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800654 vos_timer_stop ( &curr_peer->peerIdleTimer );
655 vos_timer_destroy ( &curr_peer->peerIdleTimer );
656 }
657 }
658}
659
Hoonki Lee387663d2013-02-05 18:08:43 -0800660/* if mac address exist, return pointer
661 if mac address doesn't exist, create a list and add, return pointer
662 return NULL if fails to get new mac address
663*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800664hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530665{
Hoonki Lee387663d2013-02-05 18:08:43 -0800666 struct list_head *head;
667 hddTdlsPeer_t *peer;
668 u8 key;
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700669 tdlsCtx_t *pHddTdlsCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800670
Hoonki Lee387663d2013-02-05 18:08:43 -0800671 /* if already there, just update */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800672 peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800673 if (peer != NULL)
674 {
675 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530676 }
677
Hoonki Lee387663d2013-02-05 18:08:43 -0800678 /* not found, allocate and add the list */
679 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
680 if (NULL == peer) {
681 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
682 return NULL;
683 }
Chilam NG571c65a2013-01-19 12:27:36 +0530684
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800685 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -0800686 {
687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700688 "%s: unable to lock list", __func__);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700689 vos_mem_free(peer);
Hoonki Lee387663d2013-02-05 18:08:43 -0800690 return NULL;
691 }
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700692 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
693
694 if (NULL == pHddTdlsCtx)
695 {
696 vos_mem_free(peer);
697 mutex_unlock(&tdls_lock);
698 return NULL;
699 }
700
701 key = wlan_hdd_tdls_hash_key(mac);
702 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530703
Hoonki Lee387663d2013-02-05 18:08:43 -0800704 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
705 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800706 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800707
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800708 vos_timer_init(&peer->peerIdleTimer,
709 VOS_TIMER_TYPE_SW,
710 wlan_hdd_tdls_idle_cb,
711 peer);
712
Hoonki Lee387663d2013-02-05 18:08:43 -0800713 list_add_tail(&peer->node, head);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800714 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800715
716 return peer;
717}
718
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700719int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -0700720 u8* mac,
721 tTDLSCapType cap)
722{
723 hddTdlsPeer_t *curr_peer;
724
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700725 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -0700726 if (curr_peer == NULL)
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700727 return -1;
Hoonki Lee27511902013-03-14 18:19:06 -0700728
729 curr_peer->tdls_support = cap;
730
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700731 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -0700732}
733
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800734void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800735{
736 if (curr_peer == NULL)
737 return;
738
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800739 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800740 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530741
742 curr_peer->link_status = status;
743
Chilam NG571c65a2013-01-19 12:27:36 +0530744}
745
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800746void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
747 u8* mac,
748 tTDLSLinkStatus linkStatus)
749{
750 hddTdlsPeer_t *curr_peer;
751
752 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
753 if (curr_peer == NULL)
754 return;
755
756 curr_peer->link_status= linkStatus;
757
758 return;
759}
760
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800761int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530762{
763 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700764 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530765
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800766 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700767
768 if (NULL == curr_peer)
Hoonki Lee387663d2013-02-05 18:08:43 -0800769 return -1;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700770
771 if (pHddTdlsCtx->discovery_sent_cnt)
772 pHddTdlsCtx->discovery_sent_cnt--;
773
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700774 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700775 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700776 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700777 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700778 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700779
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800780 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700781 "Discovery(%lu) Response from " MAC_ADDRESS_STR " link_status %d",
782 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
783 curr_peer->link_status);
784
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800785 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800786 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -0700787 /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI
788 threshold is also met before setting up TDLS link*/
789 if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold)
790 {
791 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
792 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
793 "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" ,
794 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
795 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
796 cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL);
797 }
798 else
799 {
800 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
801 "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ",
802 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
803 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
804 curr_peer->link_status = eTDLS_LINK_IDLE;
805 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800806 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700807 else
808 {
809 wlan_hdd_tdls_check_bmps(pAdapter);
810 }
Chilam NG571c65a2013-01-19 12:27:36 +0530811
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800812 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -0800813 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530814}
815
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800816int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +0530817{
818 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530819
Shailender Karmuchi13c0d082013-03-26 14:41:39 -0700820 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800821 if (curr_peer == NULL)
822 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530823
824 curr_peer->rssi = rxRssi;
825
Hoonki Lee387663d2013-02-05 18:08:43 -0800826 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530827}
828
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800829int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -0800830{
831 hddTdlsPeer_t *curr_peer;
832
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800833 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800834 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800835 return -1;
836
837 curr_peer->is_responder = responder;
838
839 return 0;
840}
841
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800842int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -0800843{
844 hddTdlsPeer_t *curr_peer;
845
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800846 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800847 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800848 return -1;
849
850 return (curr_peer->is_responder);
851}
852
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800853int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800854{
855 hddTdlsPeer_t *curr_peer;
856
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800857 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800858 if (curr_peer == NULL)
859 return -1;
860
861 curr_peer->signature = uSignature;
862
863 return 0;
864}
865
Hoonki Leea34dd892013-02-05 22:56:02 -0800866
Hoonki Lee387663d2013-02-05 18:08:43 -0800867void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530868{
Chilam NG571c65a2013-01-19 12:27:36 +0530869 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +0530870}
871
Hoonki Lee387663d2013-02-05 18:08:43 -0800872void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -0800873{
Chilam Ng1279e232013-01-25 15:06:52 -0800874 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -0800875}
876
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800877int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +0530878{
Hoonki Lee387663d2013-02-05 18:08:43 -0800879 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800880 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530881
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800882 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
883 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -0800884
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800885 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800886 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +0530887 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530888
Chilam Ng1279e232013-01-25 15:06:52 -0800889 if (tx)
890 curr_peer->tx_pkt++;
891 else
892 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +0530893
Chilam NG571c65a2013-01-19 12:27:36 +0530894 return 0;
895}
896
Hoonki Lee27511902013-03-14 18:19:06 -0700897static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
898{
899 if (config->tdls > 2)
900 {
901 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
902 return -1;
903 }
904 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
905 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
906 {
907 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%d>", __func__, config->tx_period_t,
908 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
909 return -1;
910 }
911 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
912 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
913 {
914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%d>", __func__, config->tx_packet_n,
915 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
916 return -1;
917 }
918 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
919 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
920 {
921 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%d>", __func__, config->discovery_period_t,
922 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
923 return -1;
924 }
925 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
926 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
927 {
928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
929 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
930 return -1;
931 }
932 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
933 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
936 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
937 return -1;
938 }
939 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
940 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
941 {
942 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
943 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
944 return -1;
945 }
946 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
947 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
948 {
949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
950 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
951 return -1;
952 }
953 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
954 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
955 {
956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
957 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
958 return -1;
959 }
960 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
961 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
962 {
963 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
964 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
965 return -1;
966 }
967 return 0;
968}
969
Chilam Ng01120412013-02-19 18:32:21 -0800970int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +0530971{
Chilam Ng01120412013-02-19 18:32:21 -0800972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
973 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800974 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -0700975 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -0800976
Hoonki Lee27511902013-03-14 18:19:06 -0700977 if (NULL == pHddTdlsCtx)
978 {
979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
980 return -1;
Chilam Ng01120412013-02-19 18:32:21 -0800981 }
Chilam NG571c65a2013-01-19 12:27:36 +0530982
Hoonki Lee27511902013-03-14 18:19:06 -0700983 if (wlan_hdd_tdls_check_config(config) != 0)
984 {
985 return -1;
986 }
987
988 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
989 req_tdls_mode = config->tdls + 1;
990 if (pHddCtx->tdls_mode == req_tdls_mode)
991 {
992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
993 return -1;
994 }
995
996 /* copy the configuration only when given tdls mode is implicit trigger enable */
997 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
998 {
Chilam Ng01120412013-02-19 18:32:21 -0800999 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1000 }
Chilam NG571c65a2013-01-19 12:27:36 +05301001
Chilam Ng01120412013-02-19 18:32:21 -08001002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1003 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1004 config->tdls,
1005 config->tx_period_t,
1006 config->tx_packet_n,
1007 config->discovery_period_t,
1008 config->discovery_tries_n,
1009 config->idle_timeout_t,
1010 config->idle_packet_n,
1011 config->rssi_hysteresis,
1012 config->rssi_trigger_threshold,
1013 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301014
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001015 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE);
Chilam Ng01120412013-02-19 18:32:21 -08001016
Chilam NG571c65a2013-01-19 12:27:36 +05301017 return 0;
1018}
1019
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001020int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001021{
Hoonki Lee387663d2013-02-05 18:08:43 -08001022 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001023
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001024 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001025 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +05301026 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301027
Hoonki Lee387663d2013-02-05 18:08:43 -08001028 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301029
1030 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001031}
1032
Hoonki Lee387663d2013-02-05 18:08:43 -08001033/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1034 otherwise, it returns NULL
1035*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001036hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac)
Kiran V1ccee932012-12-12 14:49:46 -08001037{
Hoonki Lee387663d2013-02-05 18:08:43 -08001038 u8 key;
1039 struct list_head *pos;
1040 struct list_head *head;
1041 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001042 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -08001043
Hoonki Lee387663d2013-02-05 18:08:43 -08001044
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001045 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -08001046 {
1047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1048 "%s: unable to lock list", __func__);
1049 return NULL;
1050 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001051 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001052 if (NULL == pHddTdlsCtx)
1053 {
1054 mutex_unlock(&tdls_lock);
1055 return NULL;
1056 }
1057
1058 key = wlan_hdd_tdls_hash_key(mac);
1059
1060 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001061
1062 list_for_each(pos, head) {
1063 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1064 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1065 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1066 "findTdlsPeer: found staId %d", curr_peer->staId);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001067 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001068 return curr_peer;
1069 }
1070 }
1071
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001072 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001073 return NULL;
1074}
1075
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001076int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001077{
Chilam Ng01120412013-02-19 18:32:21 -08001078 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301079 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001080
Chilam Ng01120412013-02-19 18:32:21 -08001081 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1082
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001083 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001084 if (curr_peer == NULL)
1085 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301086
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001087 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001088 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001089
Chilam Ng01120412013-02-19 18:32:21 -08001090 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001091 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001092 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001093 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001094}
1095
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001096/* Caller has to take the lock before calling this function */
Hoonki Lee27511902013-03-14 18:19:06 -07001097static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1098{
1099 int i;
1100 struct list_head *head;
1101 hddTdlsPeer_t *tmp;
1102 struct list_head *pos, *q;
1103
Hoonki Lee27511902013-03-14 18:19:06 -07001104 for (i = 0; i < 256; i++) {
1105 head = &pHddTdlsCtx->peer_list[i];
1106 list_for_each_safe (pos, q, head) {
1107 tmp = list_entry(pos, hddTdlsPeer_t, node);
1108 tmp->tx_pkt = 0;
1109 tmp->rx_pkt = 0;
1110 }
1111 }
Hoonki Lee27511902013-03-14 18:19:06 -07001112
1113 return ;
1114}
1115
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001116/* Caller has to take the lock before calling this function */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001117static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001118{
1119 int i;
1120 struct list_head *head;
1121 hddTdlsPeer_t *tmp;
1122 struct list_head *pos, *q;
1123
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001124 pHddTdlsCtx->discovery_peer_cnt = 0;
1125
1126 for (i = 0; i < 256; i++) {
1127 head = &pHddTdlsCtx->peer_list[i];
1128 list_for_each_safe (pos, q, head) {
1129 tmp = list_entry(pos, hddTdlsPeer_t, node);
1130 tmp->discovery_processed = 0;
1131 }
1132 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001133
1134 return 0;
1135}
1136
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001137static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001138{
1139 int i;
1140 struct list_head *head;
1141 struct list_head *pos, *q;
1142 int discovery_peer_cnt=0;
1143 hddTdlsPeer_t *tmp;
1144
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001145 /*
1146 * This function expects the callers to acquire the Mutex.
1147 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001148
1149 for (i = 0; i < 256; i++) {
1150 head = &pHddTdlsCtx->peer_list[i];
1151 list_for_each_safe (pos, q, head) {
1152 tmp = list_entry(pos, hddTdlsPeer_t, node);
1153 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001154 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1155 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001156 discovery_peer_cnt++;
1157 }
1158 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001159 return discovery_peer_cnt;
1160}
1161
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001162tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001163{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001164 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1165
1166 if (NULL == pHddCtx)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001167 return 0;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001168
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001169 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001170}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001171
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001172int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001173{
1174 int i;
1175 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001176 struct list_head *head;
1177 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001178 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001179 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001180
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001181
1182 init_len = buflen;
1183 len = snprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", "MAC", "Id", "cap", "up", "RSSI");
1184 buf += len;
1185 buflen -= len;
1186 /* 1234567890123456789012345678901234567 */
1187 len = snprintf(buf, buflen, "---------------------------------\n");
1188 buf += len;
1189 buflen -= len;
1190
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001191 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001192 {
1193 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1194 "%s: unable to lock list", __func__);
1195 return init_len-buflen;
1196 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001197 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001198 if (NULL == pHddTdlsCtx) {
1199 mutex_unlock(&tdls_lock);
1200 len = snprintf(buf, buflen, "TDLS not enabled\n");
1201 return len;
1202 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001203 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001204 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001205
Hoonki Lee387663d2013-02-05 18:08:43 -08001206 list_for_each(pos, head) {
1207 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001208
Hoonki Lee387663d2013-02-05 18:08:43 -08001209 if (buflen < 32+1)
1210 break;
1211 len = snprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001212 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1213 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001214 curr_peer->staId,
1215 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001216 TDLS_IS_CONNECTED(curr_peer) ? "Y":"N",
Hoonki Lee387663d2013-02-05 18:08:43 -08001217 curr_peer->rssi);
1218 buf += len;
1219 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001220 }
1221 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001222 mutex_unlock(&tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001223 return init_len-buflen;
1224}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001225
1226void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1227{
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001228 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001229 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001230
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001231 if (mutex_lock_interruptible(&tdls_lock))
1232 {
1233 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1234 "%s: unable to lock list", __func__);
1235 return;
1236 }
1237
1238 if (NULL == pHddCtx || NULL == pHddTdlsCtx)
1239 {
1240 mutex_unlock(&tdls_lock);
1241 return;
1242 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001243
1244 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1245 "%s, update %d discover %d", __func__,
1246 pHddTdlsCtx->threshold_config.tx_period_t,
1247 pHddTdlsCtx->threshold_config.discovery_period_t);
1248
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001249 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1250 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001251 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001252 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001253 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001254
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001255#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001256 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1257 &pHddTdlsCtx->peerDiscoverTimer,
1258 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001259#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001260 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1261 &pHddTdlsCtx->peerUpdateTimer,
1262 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001263 }
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001264 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001265
1266}
1267
1268void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1269{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001270 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001271
1272 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1273
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001274 if (mutex_lock_interruptible(&tdls_lock))
1275 {
1276 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1277 "%s: unable to lock list", __func__);
1278 return;
1279 }
1280 if (NULL == pHddTdlsCtx)
1281 {
1282 mutex_unlock(&tdls_lock);
1283 return;
1284 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001285 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001286 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001287
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001288 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
1289 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001290
1291 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001292}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001293
1294void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1295{
1296 pAdapter->mgmtTxCompletionStatus = statusCode;
1297 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1298 __func__, statusCode);
1299 complete(&pAdapter->tdls_mgmt_comp);
1300}
1301
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001302void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001303{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001304 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001305
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001306 if (NULL == pHddCtx) return;
1307
1308 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001309 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001310
1311 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1312 __func__, pHddCtx->connected_peer_count);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001313}
1314
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001315void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001316{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001317 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001318
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001319 if (NULL == pHddCtx) return;
1320
1321 if (pHddCtx->connected_peer_count)
1322 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001323 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001324
1325 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1326 __func__, pHddCtx->connected_peer_count);
1327
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001328}
1329
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001330void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001331{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001333 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001334
Gopichand Nakkala16c02842013-03-18 12:31:35 -07001335 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001336
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001337 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
1338 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001339 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001340 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001341 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1342 {
1343 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001344 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1345 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001346 hdd_enable_bmps_imps(pHddCtx);
1347 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001348 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001349 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001350 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001351 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1352 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001353 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1354 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001355 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1356 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001357 }
1358 return;
1359}
1360
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001361u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
1362{
1363 hddTdlsPeer_t *curr_peer;
1364
1365 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
1366 if (curr_peer == NULL)
1367 return 0;
1368
1369 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
1370}
1371
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001372/* return TRUE if TDLS is ongoing
1373 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1374 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1375 mac is NULL, this argument is ignored, and check for all the peer list.
1376 */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001377u8 wlan_hdd_tdls_is_progress(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001378{
1379 int i;
1380 struct list_head *head;
1381 hddTdlsPeer_t *curr_peer;
1382 struct list_head *pos;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001383 tdlsCtx_t *pHddTdlsCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001384
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001385 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001386 {
1387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1388 "%s: unable to lock list", __func__);
1389 return FALSE;
1390 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001391 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001392 if (NULL == pHddTdlsCtx)
1393 {
1394 mutex_unlock(&tdls_lock);
1395 return FALSE;
1396 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001397
1398 for (i = 0; i < 256; i++) {
1399 head = &pHddTdlsCtx->peer_list[i];
1400 list_for_each(pos, head) {
1401 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1402 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1403 continue;
1404 }
1405 else
1406 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001407 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001408 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001409 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001410 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001411 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001412 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001413 return TRUE;
1414 }
1415 }
1416 }
1417 }
1418
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001419 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001420 return FALSE;
1421}
Hoonki Lee27511902013-03-14 18:19:06 -07001422
1423static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1424{
Hoonki Lee27511902013-03-14 18:19:06 -07001425 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07001426}
1427
1428static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1429{
1430 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001431 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001432 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001433 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001434
Hoonki Lee27511902013-03-14 18:19:06 -07001435
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001436#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001437 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1438 &pHddTdlsCtx->peerDiscoverTimer,
1439 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001440#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001441 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1442 &pHddTdlsCtx->peerUpdateTimer,
1443 pHddTdlsCtx->threshold_config.tx_period_t);
Hoonki Lee27511902013-03-14 18:19:06 -07001444}
1445
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001446void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
1447 eTDLSSupportMode tdls_mode,
1448 v_BOOL_t bUpdateLast)
Hoonki Lee27511902013-03-14 18:19:06 -07001449{
1450 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1451 VOS_STATUS status;
1452 hdd_adapter_t *pAdapter;
1453 tdlsCtx_t *pHddTdlsCtx;
1454
1455 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
1456
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001457 if (mutex_lock_interruptible(&tdls_lock))
1458 {
1459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1460 "%s: unable to lock list", __func__);
1461 return;
1462 }
1463
1464 if (NULL == pHddCtx)
1465 {
1466 mutex_unlock(&tdls_lock);
1467 return;
1468 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001469
1470 if (pHddCtx->tdls_mode == tdls_mode)
1471 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001472 hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001473 mutex_unlock(&tdls_lock);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001474 return;
1475 }
1476
Hoonki Lee27511902013-03-14 18:19:06 -07001477 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1478
1479 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1480 {
1481 pAdapter = pAdapterNode->pAdapter;
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001482 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1483 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Hoonki Lee27511902013-03-14 18:19:06 -07001484 {
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001485 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1486 if (NULL != pHddTdlsCtx)
1487 {
1488 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
1489 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
1490 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
1491 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
1492 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
1493 }
Hoonki Lee27511902013-03-14 18:19:06 -07001494 }
1495 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1496 pAdapterNode = pNext;
1497 }
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001498 if(bUpdateLast)
1499 {
1500 pHddCtx->tdls_mode_last = tdls_mode;
1501 }
1502 else
1503 {
1504 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
1505 }
Hoonki Lee27511902013-03-14 18:19:06 -07001506 pHddCtx->tdls_mode = tdls_mode;
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001507
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001508 mutex_unlock(&tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -07001509}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001510
1511void wlan_hdd_tdls_pre_setup(tdlsCtx_t *pHddTdlsCtx,
1512 hddTdlsPeer_t *curr_peer)
1513{
1514 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1515
1516 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
1517 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001518 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001519 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1520 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001521
1522 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
1523 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
1524
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001525 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
1526 pHddTdlsCtx->pAdapter->sessionId,
1527 curr_peer->peerMac,
1528 WLAN_TDLS_DISCOVERY_REQUEST,
1529 1, 0, NULL, 0, 0);
1530 pHddTdlsCtx->discovery_sent_cnt++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001531 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001532 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %lu timeout %lu msec",
1533 __func__, pHddTdlsCtx->discovery_sent_cnt,
1534 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001535
1536 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1537 &pHddTdlsCtx->peerDiscoveryTimeoutTimer,
1538 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001539
1540 return;
1541}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001542
1543tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
1544{
1545 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1546 hdd_adapter_t *pAdapter = NULL;
1547 tdlsCtx_t *pHddTdlsCtx = NULL;
1548 VOS_STATUS status = 0;
1549 tANI_U32 count = 0;
1550
1551 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1552 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1553 {
1554 pAdapter = pAdapterNode->pAdapter;
1555
1556 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1557 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
1558 {
1559 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1560 if (NULL != pHddTdlsCtx)
1561 {
1562 count = count + pHddTdlsCtx->discovery_sent_cnt;
1563 }
1564 }
1565 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1566 pAdapterNode = pNext;
1567 }
1568 return count;
1569}
1570
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001571void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001572{
1573 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1574 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1575
1576 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
1577 return;
1578
1579 if ((0 == pHddCtx->connected_peer_count) &&
1580 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
1581 {
1582 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
1583 return;
1584 }
1585 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
1586 return;
1587}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001588
1589void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
1590{
1591 if (NULL == tdls_scan_ctx)
1592 return;
1593
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001594 tdls_scan_ctx->attempt = 0;
1595 tdls_scan_ctx->magic = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001596 tdls_scan_ctx->scan_request = NULL;
1597 return;
1598}
1599
1600int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
1601 struct wiphy *wiphy,
1602#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1603 struct net_device *dev,
1604#endif
1605 struct cfg80211_scan_request *request)
1606{
1607 tdls_scan_context_t *scan_ctx;
1608
1609 if (NULL == pHddCtx )
1610 return -1;
1611
1612 scan_ctx = &pHddCtx->tdls_scan_ctxt;
1613
1614 scan_ctx->wiphy = wiphy;
1615#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1616 scan_ctx->dev = dev;
1617#endif
1618
1619 scan_ctx->scan_request = request;
1620 return 0;
1621}
1622
1623static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
1624{
1625 tdls_scan_context_t *scan_ctx =
1626 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
1627
1628 if (NULL == scan_ctx)
1629 return;
1630
1631 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
1632 return;
1633
1634 scan_ctx->attempt++;
1635
1636 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
1637#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1638 scan_ctx->dev,
1639#endif
1640 scan_ctx->scan_request);
1641}
1642
1643static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
1644 struct wiphy *wiphy,
1645#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1646 struct net_device *dev,
1647#endif
1648 struct cfg80211_scan_request *request,
1649 unsigned long delay)
1650{
1651 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
1652 {
1653#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1654 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
1655#else
1656 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
1657#endif
1658 pHddCtx->tdls_scan_ctxt.attempt = 0;
1659 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
1660 }
1661 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
1662
1663 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
1664}
1665
1666/* return negative = caller should stop and return error code immediately
1667 return 0 = caller should stop and return success immediately
1668 return 1 = caller can continue to scan
1669 */
1670int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
1671 struct wiphy *wiphy,
1672#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1673 struct net_device *dev,
1674#endif
1675 struct cfg80211_scan_request *request)
1676{
1677#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
1678 struct net_device *dev = request->wdev->netdev;
1679#endif
1680 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1681 u16 connectedTdlsPeers;
1682 unsigned long delay;
1683
1684 if (NULL == pHddCtx)
1685 return 0;
1686
1687 /* if tdls is not enabled, then continue scan */
1688 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
1689 return 1;
1690
1691 if (wlan_hdd_tdls_is_progress(pAdapter, NULL, 0))
1692 {
1693 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1694 "%s: tdls in progress. scan rejected",
1695 __func__);
1696 return -EBUSY;
1697 }
1698
1699 /* tdls teardown is ongoing */
1700 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
1701 {
1702 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
1703 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
1704 {
1705 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
1706 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1707 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
1708 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
1709
1710 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
1711#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1712 dev,
1713#endif
1714 request,
1715 msecs_to_jiffies(delay));
1716 /* scan should not continue */
1717 return 0;
1718 }
1719 /* no connected peer or max retry reached, scan continue */
1720 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1721 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
1722 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
1723 return 1;
1724 }
1725 /* while tdls is up, first time scan */
1726 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
1727 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
1728 {
1729 /* disable implicit trigger logic & tdls operatoin */
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001730 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001731 /* indicate the teardown all connected to peer */
1732 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
1733 if (connectedTdlsPeers)
1734 {
1735 tANI_U8 staIdx;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001736 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001737
1738 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
1739 {
1740 if (pHddCtx->tdlsConnInfo[staIdx].staId)
1741 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001742 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001743 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
1744
1745#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001746 curr_peer = wlan_hdd_tdls_find_peer(pAdapter,pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
1747 wlan_hdd_tdls_indicate_teardown(pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001748#endif
1749 }
1750 }
1751 /* schedule scan */
1752 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
1753
1754 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1755 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
1756 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
1757 delay);
1758
1759 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
1760#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1761 dev,
1762#endif
1763 request,
1764 msecs_to_jiffies(delay));
1765 /* scan should not continue */
1766 return 0;
1767 }
1768 /* no connected peer, scan continue */
1769 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1770 "%s: tdls_mode %d, and no tdls connection. scan allowed",
1771 __func__, pHddCtx->tdls_mode);
1772 }
1773 return 1;
1774}
1775
1776void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
1777{
1778 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001779
1780 if (NULL == pHddCtx)
1781 return;
1782
1783 /* free allocated memory at scan time */
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001784 wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001785
1786 /* if tdls was enabled before scan, re-enable tdls mode */
1787 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
1788 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
1789 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001790 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001791 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
1792
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001793 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001794 }
1795 wlan_hdd_tdls_check_bmps(pAdapter);
1796}
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001797
1798void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
1799 vos_timer_t *timer,
1800 v_U32_t expirationTime)
1801{
1802 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1803
1804 if (NULL == pHddStaCtx)
1805 return;
1806
1807 /* Check whether driver load unload is in progress */
1808 if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
1809 {
1810 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
1811 "%s: Driver load/unload is in progress.", __func__);
1812 return;
1813 }
1814
1815 if (hdd_connIsConnected(pHddStaCtx))
1816 {
1817 vos_timer_stop(timer);
1818 vos_timer_start(timer, expirationTime);
1819 }
1820}
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001821void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
1822 hddTdlsPeer_t *curr_peer,
1823 tANI_U16 reason)
1824{
1825 if (NULL == pAdapter || NULL == curr_peer)
1826 return;
1827
1828 if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
1829 return;
1830
1831 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING);
1832 cfg80211_tdls_oper_request(pAdapter->dev,
1833 curr_peer->peerMac,
1834 NL80211_TDLS_TEARDOWN,
1835 reason,
1836 GFP_KERNEL);
1837}