blob: 87e57239de8d10306e0cf159dab52a355cab20b1 [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 Nakkala4327a152013-03-04 23:22:42 -080042static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
43static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
44static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +053045static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Hoonki Leed37cbb32013-04-20 00:31:14 -070046#ifdef CONFIG_TDLS_IMPLICIT
47static void wlan_hdd_tdls_pre_setup(struct work_struct *work);
48#endif
Chilam NG571c65a2013-01-19 12:27:36 +053049
Hoonki Lee5a4b2172013-01-29 01:45:53 -080050#ifndef WLAN_FEATURE_TDLS_DEBUG
51#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
52#else
53#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN
54#endif
55
Hoonki Lee387663d2013-02-05 18:08:43 -080056static u8 wlan_hdd_tdls_hash_key (u8 *mac)
Hoonki Leef63df0d2013-01-16 19:29:14 -080057{
58 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -080059 u8 key = 0;
60
61 for (i = 0; i < 6; i++)
62 key ^= mac[i];
63
64 return key;
65}
66
Hoonki Leed37cbb32013-04-20 00:31:14 -070067#ifdef CONFIG_TDLS_IMPLICIT
68static void wlan_hdd_tdls_pre_setup_init_work(tdlsCtx_t * pHddTdlsCtx,
69 hddTdlsPeer_t *curr_candidate)
70{
71 if (TDLS_CTX_MAGIC != pHddTdlsCtx->magic)
72 {
73 pHddTdlsCtx->curr_candidate = curr_candidate;
74 pHddTdlsCtx->magic = TDLS_CTX_MAGIC;
75
76 INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
77 schedule_work(&pHddTdlsCtx->implicit_setup);
78 }
79}
80#endif
81
Gopichand Nakkala4327a152013-03-04 23:22:42 -080082static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx,
83 tANI_BOOLEAN mutexLock,
84 v_U32_t discoveryExpiry)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080085{
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080086 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053087 hdd_context_t *pHddCtx;
88
89 if ((NULL == pHddTdlsCtx))
90 return;
91
92 if ((NULL == pHddTdlsCtx->pAdapter) )
93 return;
94
95 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
96
97 if (NULL == pHddCtx)
98 return;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080099
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800100 if ( mutexLock )
101 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530102 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800103 {
104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
105 "%s: unable to lock list: %d", __func__, __LINE__);
106 return;
107 }
108 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800109
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800110 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700111#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700112 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
113 &pHddTdlsCtx->peerDiscoverTimer,
114 discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700115#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700116 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
117 pHddTdlsCtx->ap_rssi);
118
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800119 if ( mutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530120 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800121
122 return;
123}
124
Hoonki Leed37cbb32013-04-20 00:31:14 -0700125#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Hoonki Lee387663d2013-02-05 18:08:43 -0800126static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
127{
128 int i;
129 struct list_head *head;
130 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530131 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800132 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530133 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800134 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800135 int discover_req_sent = 0;
136 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800137 tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800138
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530139 if ((NULL == pHddTdlsCtx))
140 return;
141
142 if (NULL == pHddTdlsCtx->pAdapter)
143 return;
144
145 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
146
147 if (NULL == pHddCtx)
148 return;
149
150
151 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800152 {
153 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
154 "%s: unable to lock list : %d", __func__, __LINE__);
155 return;
156 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800157
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800158 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800159
Hoonki Lee387663d2013-02-05 18:08:43 -0800160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
161
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800162 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800163 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800164
Chilam NG571c65a2013-01-19 12:27:36 +0530165 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800166 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530167
Hoonki Lee387663d2013-02-05 18:08:43 -0800168 list_for_each (pos, head) {
169 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530170
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800171 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800172 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
173 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800174 curr_peer->discovery_processed,
175 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800176 curr_peer->tdls_support,
177 curr_peer->link_status,
178 curr_peer->discovery_attempt,
179 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800180
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800181 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
182 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530183
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800184 curr_peer->discovery_processed = 1;
185 discover_req_sent++;
186 pHddTdlsCtx->discovery_peer_cnt--;
187
188 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800189 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800190 (curr_peer->tx_pkt >=
191 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800192
193 if (curr_peer->discovery_attempt <
194 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800195 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
196 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800197 curr_peer->peerMac,
198 WLAN_TDLS_DISCOVERY_REQUEST,
199 1, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800200 curr_peer->discovery_attempt++;
201 }
202 else
203 {
204 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
205 "%s: Maximum Discovery retries reached", __func__);
206 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
207 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800208
209 }
210 }
Chilam NG571c65a2013-01-19 12:27:36 +0530211 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800212 else
213 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800214 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800215 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800216exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800217
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800218 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
219 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
220 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
221 pHddTdlsCtx->discovery_peer_cnt);
222 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800223 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800224 goto done;
225 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800226 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
227
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800228 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530229
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530230 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -0700231
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800232 /* Commenting out the following function as it was introducing
233 * a race condition when pHddTdlsCtx is deleted. Also , this
234 * function is consuming more time in the timer callback.
235 * RSSI based trigger needs to revisit this part of the code.
236 */
237
238 /*
239 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
240 */
Chilam NG571c65a2013-01-19 12:27:36 +0530241
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800242done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800243 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800244
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800245 if ( !doMutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530246 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800247 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800248}
Hoonki Leed37cbb32013-04-20 00:31:14 -0700249#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530250
Hoonki Lee387663d2013-02-05 18:08:43 -0800251static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530252{
253 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800254 struct list_head *head;
255 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530256 hddTdlsPeer_t *curr_peer;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530257 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
258 hdd_context_t *pHddCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800259
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530260 if ((NULL == pHddTdlsCtx))
261 return;
262
263 if (NULL == pHddTdlsCtx->pAdapter)
264 return;
265
266 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
267
268 if (NULL == pHddCtx)
269 return;
270
271 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800272 {
273 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
274 "%s: unable to lock list", __func__);
275 return;
276 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800277
Chilam NG571c65a2013-01-19 12:27:36 +0530278 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800279 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530280
Hoonki Lee387663d2013-02-05 18:08:43 -0800281 list_for_each (pos, head) {
282 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530283
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800284 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700285 "%s: " MAC_ADDRESS_STR " link_status %d"
286 " tdls_support %d", __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700287 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800288
Chilam NG571c65a2013-01-19 12:27:36 +0530289 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800290 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700291 "tx %d, rx %d (thr.pkt %d/idle %d), rssi %d (thr.trig %d/hys %d/tear %d)",
292 curr_peer->tx_pkt, curr_peer->rx_pkt,
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800293 pHddTdlsCtx->threshold_config.tx_packet_n,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700294 pHddTdlsCtx->threshold_config.idle_packet_n,
295 curr_peer->rssi,
296 pHddTdlsCtx->threshold_config.rssi_trigger_threshold,
297 pHddTdlsCtx->threshold_config.rssi_hysteresis,
298 pHddTdlsCtx->threshold_config.rssi_teardown_threshold);
Chilam Ng01120412013-02-19 18:32:21 -0800299
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800300 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
301 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Chilam NG571c65a2013-01-19 12:27:36 +0530302 if (curr_peer->tx_pkt >=
303 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800304
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800305 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800306 {
307
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700308 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530309#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leed37cbb32013-04-20 00:31:14 -0700310 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530311#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800312 }
313 else
314 {
315 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800316 "%s: Maximum peer connected already! %d",
317 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800318 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800319 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530320 }
Hoonki Leefb8df672013-04-10 18:20:34 -0700321 }
322 else if (eTDLS_LINK_CONNECTED == curr_peer->link_status) {
Chilam Ng01120412013-02-19 18:32:21 -0800323 if ((tANI_S32)curr_peer->rssi <
324 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800325
Chilam Ng01120412013-02-19 18:32:21 -0800326 VOS_TRACE( VOS_MODULE_ID_HDD,
327 VOS_TRACE_LEVEL_WARN,
328 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
329 MAC_ADDR_ARRAY(curr_peer->peerMac));
330#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700331 wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
332 curr_peer,
333 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Chilam Ng01120412013-02-19 18:32:21 -0800334#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800335 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530336 }
Chilam Ng01120412013-02-19 18:32:21 -0800337
338 if ((curr_peer->tx_pkt <
339 pHddTdlsCtx->threshold_config.idle_packet_n) &&
340 (curr_peer->rx_pkt <
341 pHddTdlsCtx->threshold_config.idle_packet_n)) {
342 if (VOS_TIMER_STATE_RUNNING !=
343 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
345 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
346 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700347 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
348 &curr_peer->peerIdleTimer,
349 pHddTdlsCtx->threshold_config.idle_timeout_t);
Chilam Ng01120412013-02-19 18:32:21 -0800350 }
351 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800352 if (VOS_TIMER_STATE_RUNNING ==
353 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
355 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
356 MAC_ADDR_ARRAY(curr_peer->peerMac));
357 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800358 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800359 }
Chilam Ng01120412013-02-19 18:32:21 -0800360
Hoonki Leecdd8e962013-01-20 00:45:46 -0800361// if (curr_peer->rssi <
362// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
363// pHddTdlsCtx->ap_rssi)) {
364//
365//#ifdef CONFIG_TDLS_IMPLICIT
366// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
367// curr_peer->peerMac,
368// NL80211_TDLS_TEARDOWN, FALSE,
369// GFP_KERNEL);
370//#endif
371// }
Chilam NG571c65a2013-01-19 12:27:36 +0530372 }
Chilam Ng01120412013-02-19 18:32:21 -0800373 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700374 if (!TDLS_IS_CONNECTED(curr_peer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800375 if (curr_peer->tx_pkt >=
376 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800377
Gopichand Nakkala062bcbd2013-03-29 18:14:47 -0700378 if (curr_peer->discovery_attempt++ <
Chilam Ng01120412013-02-19 18:32:21 -0800379 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700380 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Hoonki Leed37cbb32013-04-20 00:31:14 -0700381#ifdef CONFIG_TDLS_IMPLICIT
382 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
383#endif
Chilam Ng01120412013-02-19 18:32:21 -0800384 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800385 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800386 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800387 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800388 curr_peer->link_status = eTDLS_LINK_IDLE;
389 }
Chilam Ng01120412013-02-19 18:32:21 -0800390 }
391 }
Chilam NG571c65a2013-01-19 12:27:36 +0530392 }
393
Hoonki Leecdd8e962013-01-20 00:45:46 -0800394next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530395 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800396 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800397 }
Chilam NG571c65a2013-01-19 12:27:36 +0530398 }
399
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700400 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
401 &pHddTdlsCtx->peerUpdateTimer,
402 pHddTdlsCtx->threshold_config.tx_period_t);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530403 mutex_unlock(&pHddCtx->tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530404}
405
Chilam Ng1279e232013-01-25 15:06:52 -0800406static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
407{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800408#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800409 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530410 tdlsCtx_t *pHddTdlsCtx;
411 hdd_context_t *pHddCtx;
Chilam Ng1279e232013-01-25 15:06:52 -0800412
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700413 if (NULL == curr_peer)
414 {
415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
416 "%s: Invalid tdls idle timer expired", __func__);
417 return;
418 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530419 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
420
421 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
422 return;
423
424 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
425
426 if (NULL == pHddCtx)
427 return;
428
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700429
430 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
431 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d\n",
432 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
433 curr_peer->tx_pkt,
434 curr_peer->rx_pkt,
435 curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n);
436
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530437 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800438 {
439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
440 "%s: unable to lock list", __func__);
441 return;
442 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800443
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700444 /* Check tx/rx statistics on this tdls link for recent activities and
445 * then decide whether to tear down the link or keep it.
446 */
447 if ((curr_peer->tx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n) || (curr_peer->rx_pkt >= curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n))
448 {
449 /* this tdls link got back to normal, so keep it */
450 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
451 "%s: tdls link to " MAC_ADDRESS_STR " back to normal, will stay",
452 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
453 }
454 else
455 {
456 /* this tdls link needs to get torn down */
457 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
458 "%s: trigger tdls link to " MAC_ADDRESS_STR " down",
459 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
460
461 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
462 curr_peer,
463 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
464 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530465 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800466#endif
467}
468
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700469static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
470{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700471 int i;
472 struct list_head *head;
473 hddTdlsPeer_t *tmp;
474 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700475 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530476 hdd_context_t *pHddCtx;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700477
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530478 pHddTdlsCtx = (tdlsCtx_t *)userData;
479
480 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
481 return;
482
483 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
484
485 if (NULL == pHddCtx)
486 return;
487
488 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700489 {
490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
491 "%s: unable to lock list", __func__);
492 return ;
493 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700494
495 for (i = 0; i < 256; i++) {
496 head = &pHddTdlsCtx->peer_list[i];
497 list_for_each_safe (pos, q, head) {
498 tmp = list_entry(pos, hddTdlsPeer_t, node);
499 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
500 {
501 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
502 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
503 MAC_ADDR_ARRAY(tmp->peerMac));
504 tmp->link_status = eTDLS_LINK_IDLE;
505 }
506 }
507 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700508
509 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700510 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700511
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530512 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700513
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700514 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
515
516 return;
517}
518
Hoonki Lee14621352013-04-16 17:51:19 -0700519static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
520{
521 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
522 tdlsCtx_t *pHddTdlsCtx;
523
524 if ( NULL == curr_peer )
525 return;
526
527 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
528
529 if ( NULL == pHddTdlsCtx )
530 return;
531
532 WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext,
533 (v_U8_t *)&curr_peer->staId);
534}
535
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800536static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800537{
538 int i;
539 struct list_head *head;
540 hddTdlsPeer_t *tmp;
541 struct list_head *pos, *q;
542
543 if (NULL == pHddTdlsCtx) return;
544
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800545
546 for (i = 0; i < 256; i++) {
547 head = &pHddTdlsCtx->peer_list[i];
548 list_for_each_safe (pos, q, head) {
549 tmp = list_entry(pos, hddTdlsPeer_t, node);
550 list_del(pos);
551 vos_mem_free(tmp);
552 }
553 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800554}
555
Hoonki Lee27511902013-03-14 18:19:06 -0700556int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800557{
Chilam Ng01120412013-02-19 18:32:21 -0800558 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700559 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800560 int i;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800561 v_U8_t staIdx;
Chilam Ng01120412013-02-19 18:32:21 -0800562
Hoonki Lee27511902013-03-14 18:19:06 -0700563 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
564 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
565 {
566 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
567 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
568 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
569 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
570 sme_IsFeatureSupportedByFW(TDLS));
571 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800572 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530573 /* TDLS is supported only in STA / P2P Client modes,
574 * hence the check for TDLS support in a specific Device mode.
575 * Do not return a failure rather do not continue further
576 * with the initialization as tdls_init would be called
577 * during the open adapter for a p2p interface at which point
578 * the device mode would be a P2P_DEVICE. The point here is to
579 * continue initialization for STA / P2P Client modes.
580 * TDLS exit also check for the device mode for clean up hence
581 * there is no issue even if success is returned.
582 */
583 if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter))
584 {
585 return 0;
586 }
587 /* Check for the valid pHddTdlsCtx. If valid do not further
588 * allocate the memory, rather continue with the initialization.
589 * If tdls_initialization would get reinvoked without tdls_exit
590 * getting invoked (SSR) there is no point to further proceed
591 * with the memory allocations.
592 */
593 if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx)
594 {
595 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800596
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530597 if (NULL == pHddTdlsCtx) {
598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
599 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
600 return -1;
601 }
602 /* initialize TDLS pAdater context */
603 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
604#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
605 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
606 VOS_TIMER_TYPE_SW,
607 wlan_hdd_tdls_discover_peer_cb,
608 pHddTdlsCtx);
609#endif
Hoonki Lee27511902013-03-14 18:19:06 -0700610
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530611 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
612 VOS_TIMER_TYPE_SW,
613 wlan_hdd_tdls_update_peer_cb,
614 pHddTdlsCtx);
615 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
616 VOS_TIMER_TYPE_SW,
617 wlan_hdd_tdls_discovery_timeout_peer_cb,
618 pHddTdlsCtx);
619
620 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700621 }
622
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530623 pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700624
625 /* initialize TDLS global context */
626 pHddCtx->connected_peer_count = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700627 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700628
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700629 pHddCtx->tdls_scan_ctxt.magic = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -0700630 pHddCtx->tdls_scan_ctxt.attempt = 0;
631 pHddCtx->tdls_scan_ctxt.reject = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700632 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
633
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800634 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
635 {
636 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
637 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
638 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
639 sizeof(v_MACADDR_t)) ;
Chilam Ng01120412013-02-19 18:32:21 -0800640 }
641
Hoonki Lee27511902013-03-14 18:19:06 -0700642 pHddTdlsCtx->pAdapter = pAdapter;
643
644 for (i = 0; i < 256; i++)
645 {
646 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
647 }
648
Hoonki Leed37cbb32013-04-20 00:31:14 -0700649 pHddTdlsCtx->curr_candidate = NULL;
650 pHddTdlsCtx->magic = 0;
651
Hoonki Lee27511902013-03-14 18:19:06 -0700652 /* remember configuration even if it is not used right now. it could be used later */
653 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
654 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
655 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
656 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
657 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
658 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
659 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
660 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
661 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530662
Chilam Ng01120412013-02-19 18:32:21 -0800663 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
Hoonki Lee387663d2013-02-05 18:08:43 -0800664 {
Chilam Ng01120412013-02-19 18:32:21 -0800665 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
Hoonki Leebf870f32013-01-19 15:53:30 +0530666 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Leebf870f32013-01-19 15:53:30 +0530667 }
Hoonki Lee27511902013-03-14 18:19:06 -0700668 else
669 {
670 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
Hoonki Lee27511902013-03-14 18:19:06 -0700671 }
672
673 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530674}
675
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800676void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530677{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800678 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700679 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800680
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530681 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
682 if (NULL == pHddCtx)
683 {
684 return;
685 }
686
687 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800688 {
689 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
690 "%s: unable to lock list", __func__);
691 return;
692 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800693
694 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800695 if (NULL == pHddTdlsCtx)
696 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530697 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800698 hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
699 return;
700 }
701
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800702 /* must stop timer here before freeing peer list, because peerIdleTimer is
703 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800704 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
705 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800706
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700707 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
708
Chilam Nga75d8b62013-01-29 01:35:59 -0800709 vos_mem_free(pHddTdlsCtx);
710 pHddTdlsCtx = NULL;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530711 mutex_unlock(&pHddCtx->tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530712}
713
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530714/* stop all monitoring timers per Adapter */
715static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800716{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700717#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800718 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700719#endif
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800720 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700721 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530722}
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800723
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530724/* stop all per peer timers */
725static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx)
726{
727 int i;
728 struct list_head *head;
729 struct list_head *pos;
730 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800731 for (i = 0; i < 256; i++)
732 {
733 head = &pHddTdlsCtx->peer_list[i];
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800734 list_for_each (pos, head) {
735 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800736 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800737 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800738 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800739 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800740 vos_timer_stop ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700741 vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800742 }
743 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800744}
745
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530746/* stop all the tdls timers running */
747static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800748{
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530749 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
750 wlan_hdd_tdls_peer_timers_stop(pHddTdlsCtx);
751}
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800752
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530753static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
754{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700755#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800756 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
757 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700758#endif
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800759 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
760 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700761 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
762 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530763}
764/*Free all the timers related to the TDLS peer */
765static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
766{
767 int i;
768 struct list_head *head;
769 struct list_head *pos;
770 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800771 for (i = 0; i < 256; i++)
772 {
773 head = &pHddTdlsCtx->peer_list[i];
774
775 list_for_each (pos, head) {
776 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
777
778 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800779 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800780 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800781 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800782 vos_timer_stop ( &curr_peer->peerIdleTimer );
783 vos_timer_destroy ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700784 vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
785 vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800786 }
787 }
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530788
789}
790
791/* destroy all the tdls timers running */
792static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
793{
794 wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx);
795 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800796}
797
Hoonki Lee387663d2013-02-05 18:08:43 -0800798/* if mac address exist, return pointer
799 if mac address doesn't exist, create a list and add, return pointer
800 return NULL if fails to get new mac address
801*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800802hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530803{
Hoonki Lee387663d2013-02-05 18:08:43 -0800804 struct list_head *head;
805 hddTdlsPeer_t *peer;
806 u8 key;
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700807 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530808 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
809
810 if ((NULL == pHddCtx)) return NULL;
Hoonki Leebfee0342013-01-21 16:43:45 -0800811
Hoonki Lee387663d2013-02-05 18:08:43 -0800812 /* if already there, just update */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800813 peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800814 if (peer != NULL)
815 {
816 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530817 }
818
Hoonki Lee387663d2013-02-05 18:08:43 -0800819 /* not found, allocate and add the list */
820 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
821 if (NULL == peer) {
822 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
823 return NULL;
824 }
Chilam NG571c65a2013-01-19 12:27:36 +0530825
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530826 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -0800827 {
828 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700829 "%s: unable to lock list", __func__);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700830 vos_mem_free(peer);
Hoonki Lee387663d2013-02-05 18:08:43 -0800831 return NULL;
832 }
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700833 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
834
835 if (NULL == pHddTdlsCtx)
836 {
837 vos_mem_free(peer);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530838 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700839 return NULL;
840 }
841
842 key = wlan_hdd_tdls_hash_key(mac);
843 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530844
Hoonki Lee387663d2013-02-05 18:08:43 -0800845 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
846 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800847 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800848
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800849 vos_timer_init(&peer->peerIdleTimer,
850 VOS_TIMER_TYPE_SW,
851 wlan_hdd_tdls_idle_cb,
852 peer);
853
Hoonki Lee14621352013-04-16 17:51:19 -0700854 vos_timer_init(&peer->initiatorWaitTimeoutTimer,
855 VOS_TIMER_TYPE_SW,
856 wlan_hdd_tdls_initiator_wait_cb,
857 peer);
858
Hoonki Lee387663d2013-02-05 18:08:43 -0800859 list_add_tail(&peer->node, head);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530860 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800861
862 return peer;
863}
864
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700865int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -0700866 u8* mac,
867 tTDLSCapType cap)
868{
869 hddTdlsPeer_t *curr_peer;
870
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700871 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -0700872 if (curr_peer == NULL)
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700873 return -1;
Hoonki Lee27511902013-03-14 18:19:06 -0700874
875 curr_peer->tdls_support = cap;
876
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700877 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -0700878}
879
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800880void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800881{
882 if (curr_peer == NULL)
883 return;
884
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800885 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800886 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530887
888 curr_peer->link_status = status;
889
Chilam NG571c65a2013-01-19 12:27:36 +0530890}
891
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800892void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
893 u8* mac,
894 tTDLSLinkStatus linkStatus)
895{
896 hddTdlsPeer_t *curr_peer;
897
898 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
899 if (curr_peer == NULL)
900 return;
901
902 curr_peer->link_status= linkStatus;
903
904 return;
905}
906
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800907int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530908{
909 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700910 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530911
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800912 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700913
914 if (NULL == curr_peer)
Hoonki Lee387663d2013-02-05 18:08:43 -0800915 return -1;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700916
917 if (pHddTdlsCtx->discovery_sent_cnt)
918 pHddTdlsCtx->discovery_sent_cnt--;
919
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700920 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700921 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700922 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700923 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700924 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700925
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800926 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700927 "Discovery(%lu) Response from " MAC_ADDRESS_STR " link_status %d",
928 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
929 curr_peer->link_status);
930
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800931 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800932 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -0700933 /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI
934 threshold is also met before setting up TDLS link*/
935 if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold)
936 {
937 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
938 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
939 "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" ,
940 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
941 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
942 cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL);
943 }
944 else
945 {
946 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
947 "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ",
948 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
949 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
950 curr_peer->link_status = eTDLS_LINK_IDLE;
951 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800952 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700953 else
954 {
955 wlan_hdd_tdls_check_bmps(pAdapter);
956 }
Chilam NG571c65a2013-01-19 12:27:36 +0530957
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800958 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -0800959 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530960}
961
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +0530962int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter,
963 u8 *mac,
964 tANI_U8 uapsdQueues,
965 tANI_U8 maxSp,
966 tANI_BOOLEAN isBufSta)
967{
968 hddTdlsPeer_t *curr_peer;
969
970 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
971 if (curr_peer == NULL)
972 return -1;
973
974 curr_peer->uapsdQueues = uapsdQueues;
975 curr_peer->maxSp = maxSp;
976 curr_peer->isBufSta = isBufSta;
977 return 0;
978}
979
980int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac,
981 tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams)
982{
983 hddTdlsPeer_t *curr_peer;
984
985 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
986 if (curr_peer == NULL)
987 return -1;
988
989 tdlsLinkEstablishParams->isResponder = curr_peer->is_responder;
990 tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues;
991 tdlsLinkEstablishParams->maxSp = curr_peer->maxSp;
992 tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta;
993 return 0;
994}
995
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800996int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +0530997{
998 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530999
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001000 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001001 if (curr_peer == NULL)
1002 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301003
1004 curr_peer->rssi = rxRssi;
1005
Hoonki Lee387663d2013-02-05 18:08:43 -08001006 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301007}
1008
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001009int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08001010{
1011 hddTdlsPeer_t *curr_peer;
1012
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001013 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001014 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -08001015 return -1;
1016
1017 curr_peer->is_responder = responder;
1018
1019 return 0;
1020}
1021
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001022int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -08001023{
1024 hddTdlsPeer_t *curr_peer;
1025
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001026 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001027 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -08001028 return -1;
1029
1030 return (curr_peer->is_responder);
1031}
1032
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001033int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001034{
1035 hddTdlsPeer_t *curr_peer;
1036
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001037 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001038 if (curr_peer == NULL)
1039 return -1;
1040
1041 curr_peer->signature = uSignature;
1042
1043 return 0;
1044}
1045
Hoonki Leea34dd892013-02-05 22:56:02 -08001046
Hoonki Lee387663d2013-02-05 18:08:43 -08001047void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301048{
Chilam NG571c65a2013-01-19 12:27:36 +05301049 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +05301050}
1051
Hoonki Lee387663d2013-02-05 18:08:43 -08001052void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -08001053{
Chilam Ng1279e232013-01-25 15:06:52 -08001054 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -08001055}
1056
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001057int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +05301058{
Hoonki Lee387663d2013-02-05 18:08:43 -08001059 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001060 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +05301061
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001062 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
1063 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -08001064
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001065 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001066 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +05301067 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301068
Chilam Ng1279e232013-01-25 15:06:52 -08001069 if (tx)
1070 curr_peer->tx_pkt++;
1071 else
1072 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +05301073
Chilam NG571c65a2013-01-19 12:27:36 +05301074 return 0;
1075}
1076
Hoonki Lee27511902013-03-14 18:19:06 -07001077static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
1078{
1079 if (config->tdls > 2)
1080 {
1081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
1082 return -1;
1083 }
1084 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
1085 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
1086 {
1087 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%d>", __func__, config->tx_period_t,
1088 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
1089 return -1;
1090 }
1091 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
1092 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
1093 {
1094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%d>", __func__, config->tx_packet_n,
1095 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
1096 return -1;
1097 }
1098 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
1099 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
1100 {
1101 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%d>", __func__, config->discovery_period_t,
1102 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
1103 return -1;
1104 }
1105 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
1106 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
1107 {
1108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
1109 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
1110 return -1;
1111 }
1112 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
1113 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
1114 {
1115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
1116 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
1117 return -1;
1118 }
1119 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
1120 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
1121 {
1122 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
1123 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
1124 return -1;
1125 }
1126 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
1127 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
1128 {
1129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
1130 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
1131 return -1;
1132 }
1133 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
1134 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
1135 {
1136 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
1137 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
1138 return -1;
1139 }
1140 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
1141 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
1142 {
1143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
1144 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
1145 return -1;
1146 }
1147 return 0;
1148}
1149
Chilam Ng01120412013-02-19 18:32:21 -08001150int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +05301151{
Chilam Ng01120412013-02-19 18:32:21 -08001152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1153 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001154 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -07001155 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -08001156
Hoonki Lee27511902013-03-14 18:19:06 -07001157 if (NULL == pHddTdlsCtx)
1158 {
1159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
1160 return -1;
Chilam Ng01120412013-02-19 18:32:21 -08001161 }
Chilam NG571c65a2013-01-19 12:27:36 +05301162
Hoonki Lee27511902013-03-14 18:19:06 -07001163 if (wlan_hdd_tdls_check_config(config) != 0)
1164 {
1165 return -1;
1166 }
1167
1168 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1169 req_tdls_mode = config->tdls + 1;
1170 if (pHddCtx->tdls_mode == req_tdls_mode)
1171 {
1172 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1173 return -1;
1174 }
1175
1176 /* copy the configuration only when given tdls mode is implicit trigger enable */
1177 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1178 {
Chilam Ng01120412013-02-19 18:32:21 -08001179 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1180 }
Chilam NG571c65a2013-01-19 12:27:36 +05301181
Chilam Ng01120412013-02-19 18:32:21 -08001182 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1183 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1184 config->tdls,
1185 config->tx_period_t,
1186 config->tx_packet_n,
1187 config->discovery_period_t,
1188 config->discovery_tries_n,
1189 config->idle_timeout_t,
1190 config->idle_packet_n,
1191 config->rssi_hysteresis,
1192 config->rssi_trigger_threshold,
1193 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301194
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001195 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE);
Chilam Ng01120412013-02-19 18:32:21 -08001196
Chilam NG571c65a2013-01-19 12:27:36 +05301197 return 0;
1198}
1199
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001200int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001201{
Hoonki Lee387663d2013-02-05 18:08:43 -08001202 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001203
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001204 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001205 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +05301206 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301207
Hoonki Lee387663d2013-02-05 18:08:43 -08001208 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301209
1210 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001211}
1212
Hoonki Lee387663d2013-02-05 18:08:43 -08001213/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1214 otherwise, it returns NULL
1215*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001216hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac)
Kiran V1ccee932012-12-12 14:49:46 -08001217{
Hoonki Lee387663d2013-02-05 18:08:43 -08001218 u8 key;
1219 struct list_head *pos;
1220 struct list_head *head;
1221 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001222 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301223 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee387663d2013-02-05 18:08:43 -08001224
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301225 if ((NULL == pHddCtx)) return NULL;
Hoonki Lee387663d2013-02-05 18:08:43 -08001226
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301227 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -08001228 {
1229 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1230 "%s: unable to lock list", __func__);
1231 return NULL;
1232 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001233 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001234 if (NULL == pHddTdlsCtx)
1235 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301236 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001237 return NULL;
1238 }
1239
1240 key = wlan_hdd_tdls_hash_key(mac);
1241
1242 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001243
1244 list_for_each(pos, head) {
1245 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1246 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1248 "findTdlsPeer: found staId %d", curr_peer->staId);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301249 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001250 return curr_peer;
1251 }
1252 }
1253
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301254 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001255 return NULL;
1256}
1257
Hoonki Leea6d49be2013-04-05 09:43:25 -07001258hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac)
1259{
1260 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1261 hdd_adapter_t *pAdapter = NULL;
1262 tdlsCtx_t *pHddTdlsCtx = NULL;
1263 hddTdlsPeer_t *curr_peer= NULL;
1264 VOS_STATUS status = 0;
1265
1266 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1267 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1268 {
1269 pAdapter = pAdapterNode->pAdapter;
1270
1271 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1272 if (NULL != pHddTdlsCtx)
1273 {
1274 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
1275 if (curr_peer)
1276 return curr_peer;
1277 }
1278 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1279 pAdapterNode = pNext;
1280 }
1281 return curr_peer;
1282}
1283
1284
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001285int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001286{
Chilam Ng01120412013-02-19 18:32:21 -08001287 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301288 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001289
Chilam Ng01120412013-02-19 18:32:21 -08001290 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1291
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001292 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001293 if (curr_peer == NULL)
1294 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301295
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001296 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001297 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001298
Chilam Ng01120412013-02-19 18:32:21 -08001299 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001300 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001301 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001302 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001303}
1304
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001305/* Caller has to take the lock before calling this function */
Hoonki Lee27511902013-03-14 18:19:06 -07001306static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1307{
1308 int i;
1309 struct list_head *head;
1310 hddTdlsPeer_t *tmp;
1311 struct list_head *pos, *q;
1312
Hoonki Lee27511902013-03-14 18:19:06 -07001313 for (i = 0; i < 256; i++) {
1314 head = &pHddTdlsCtx->peer_list[i];
1315 list_for_each_safe (pos, q, head) {
1316 tmp = list_entry(pos, hddTdlsPeer_t, node);
1317 tmp->tx_pkt = 0;
1318 tmp->rx_pkt = 0;
1319 }
1320 }
Hoonki Lee27511902013-03-14 18:19:06 -07001321
1322 return ;
1323}
1324
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001325/* Caller has to take the lock before calling this function */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001326static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001327{
1328 int i;
1329 struct list_head *head;
1330 hddTdlsPeer_t *tmp;
1331 struct list_head *pos, *q;
1332
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001333 pHddTdlsCtx->discovery_peer_cnt = 0;
1334
1335 for (i = 0; i < 256; i++) {
1336 head = &pHddTdlsCtx->peer_list[i];
1337 list_for_each_safe (pos, q, head) {
1338 tmp = list_entry(pos, hddTdlsPeer_t, node);
1339 tmp->discovery_processed = 0;
1340 }
1341 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001342
1343 return 0;
1344}
1345
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001346static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001347{
1348 int i;
1349 struct list_head *head;
1350 struct list_head *pos, *q;
1351 int discovery_peer_cnt=0;
1352 hddTdlsPeer_t *tmp;
1353
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001354 /*
1355 * This function expects the callers to acquire the Mutex.
1356 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001357
1358 for (i = 0; i < 256; i++) {
1359 head = &pHddTdlsCtx->peer_list[i];
1360 list_for_each_safe (pos, q, head) {
1361 tmp = list_entry(pos, hddTdlsPeer_t, node);
1362 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001363 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1364 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001365 discovery_peer_cnt++;
1366 }
1367 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001368 return discovery_peer_cnt;
1369}
1370
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001371tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001372{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001373 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1374
1375 if (NULL == pHddCtx)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001376 return 0;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001377
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001378 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001379}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001380
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001381int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001382{
1383 int i;
1384 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001385 struct list_head *head;
1386 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001387 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001388 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301389 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1390
1391 if ((NULL == pHddCtx)) {
1392 len = snprintf(buf, buflen, "NULL HddCtx\n");
1393 return len;
1394 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001395
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001396
1397 init_len = buflen;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001398 len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n",
1399 "MAC", "Id", "cap", "up", "RSSI");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001400 buf += len;
1401 buflen -= len;
1402 /* 1234567890123456789012345678901234567 */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001403 len = scnprintf(buf, buflen, "---------------------------------\n");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001404 buf += len;
1405 buflen -= len;
1406
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301407 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001408 {
1409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1410 "%s: unable to lock list", __func__);
1411 return init_len-buflen;
1412 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001413 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001414 if (NULL == pHddTdlsCtx) {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301415 mutex_unlock(&pHddCtx->tdls_lock);
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001416 len = scnprintf(buf, buflen, "TDLS not enabled\n");
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001417 return len;
1418 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001419 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001420 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001421
Hoonki Lee387663d2013-02-05 18:08:43 -08001422 list_for_each(pos, head) {
1423 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001424
Hoonki Lee387663d2013-02-05 18:08:43 -08001425 if (buflen < 32+1)
1426 break;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001427 len = scnprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001428 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1429 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001430 curr_peer->staId,
1431 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001432 TDLS_IS_CONNECTED(curr_peer) ? "Y":"N",
Hoonki Lee387663d2013-02-05 18:08:43 -08001433 curr_peer->rssi);
1434 buf += len;
1435 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001436 }
1437 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301438 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001439 return init_len-buflen;
1440}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001441
1442void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1443{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001444 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301445 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001446
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301447 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
1448
1449 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001450 {
1451 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1452 "%s: unable to lock list", __func__);
1453 return;
1454 }
1455
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001456 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1457 "%s, update %d discover %d", __func__,
1458 pHddTdlsCtx->threshold_config.tx_period_t,
1459 pHddTdlsCtx->threshold_config.discovery_period_t);
1460
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001461 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1462 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001463 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001464 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001465 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001466
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001467#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001468 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1469 &pHddTdlsCtx->peerDiscoverTimer,
1470 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001471#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001472 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1473 &pHddTdlsCtx->peerUpdateTimer,
1474 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001475 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301476 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001477
1478}
1479
1480void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1481{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001482 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301483 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1484
1485 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001486
1487 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1488
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301489 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001490 {
1491 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1492 "%s: unable to lock list", __func__);
1493 return;
1494 }
1495 if (NULL == pHddTdlsCtx)
1496 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301497 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001498 return;
1499 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001500 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001501 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001502
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301503 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
1504 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001505 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001506
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301507 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001508}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001509
1510void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1511{
1512 pAdapter->mgmtTxCompletionStatus = statusCode;
1513 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1514 __func__, statusCode);
1515 complete(&pAdapter->tdls_mgmt_comp);
1516}
1517
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001518void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001519{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001520 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001521
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001522 if (NULL == pHddCtx) return;
1523
1524 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001525 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001526
1527 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1528 __func__, pHddCtx->connected_peer_count);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001529}
1530
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001531void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001532{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001533 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001534
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001535 if (NULL == pHddCtx) return;
1536
1537 if (pHddCtx->connected_peer_count)
1538 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001539 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001540
1541 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1542 __func__, pHddCtx->connected_peer_count);
1543
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001544}
1545
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001546void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001547{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001548 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001549 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee14621352013-04-16 17:51:19 -07001550 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001551
Gopichand Nakkala16c02842013-03-18 12:31:35 -07001552 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001553
Hoonki Lee14621352013-04-16 17:51:19 -07001554 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, TRUE);
1555 if (NULL != curr_peer)
1556 {
1557 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1558 "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR,
1559 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac));
1560 return;
1561 }
1562
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001563 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
1564 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001565 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001566 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001567 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1568 {
1569 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001570 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1571 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001572 hdd_enable_bmps_imps(pHddCtx);
1573 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001574 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001575 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001576 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001577 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1578 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001579 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1580 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001581 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1582 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001583 }
1584 return;
1585}
1586
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001587u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
1588{
1589 hddTdlsPeer_t *curr_peer;
1590
1591 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
1592 if (curr_peer == NULL)
1593 return 0;
1594
1595 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
1596}
1597
Hoonki Leefb8df672013-04-10 18:20:34 -07001598/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL.
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001599 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1600 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1601 mac is NULL, this argument is ignored, and check for all the peer list.
1602 */
Hoonki Leefb8df672013-04-10 18:20:34 -07001603static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self, tANI_BOOLEAN mutexLock)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001604{
1605 int i;
1606 struct list_head *head;
1607 hddTdlsPeer_t *curr_peer;
1608 struct list_head *pos;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001609 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301610 hdd_context_t *pHddCtx;
1611
1612 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1613 if (NULL == pHddTdlsCtx)
1614 return NULL;
1615
1616 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
1617
1618 if (NULL == pHddCtx)
1619 return NULL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001620
Hoonki Leefb8df672013-04-10 18:20:34 -07001621 if (mutexLock)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001622 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301623 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Hoonki Leefb8df672013-04-10 18:20:34 -07001624 {
1625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001626 "%s: unable to lock list", __func__);
Hoonki Leefb8df672013-04-10 18:20:34 -07001627 return NULL;
1628 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001629 }
1630
1631 for (i = 0; i < 256; i++) {
1632 head = &pHddTdlsCtx->peer_list[i];
1633 list_for_each(pos, head) {
1634 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1635 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1636 continue;
1637 }
1638 else
1639 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001640 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001641 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001642 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001643 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001644 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Hoonki Leefb8df672013-04-10 18:20:34 -07001645 if (mutexLock)
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301646 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001647 return curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001648 }
1649 }
1650 }
1651 }
1652
Hoonki Leefb8df672013-04-10 18:20:34 -07001653 if (mutexLock)
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301654 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001655 return NULL;
1656}
1657
1658hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8 *mac, u8 skip_self, tANI_BOOLEAN mutexLock)
1659{
1660 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1661 hdd_adapter_t *pAdapter = NULL;
1662 tdlsCtx_t *pHddTdlsCtx = NULL;
1663 hddTdlsPeer_t *curr_peer= NULL;
1664 VOS_STATUS status = 0;
1665
1666 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1668 {
1669 pAdapter = pAdapterNode->pAdapter;
1670
1671 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1672 if (NULL != pHddTdlsCtx)
1673 {
1674 curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self, mutexLock);
1675 if (curr_peer)
1676 return curr_peer;
1677 }
1678 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1679 pAdapterNode = pNext;
1680 }
1681 return NULL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001682}
Hoonki Lee27511902013-03-14 18:19:06 -07001683
1684static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1685{
Hoonki Lee27511902013-03-14 18:19:06 -07001686 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07001687}
1688
1689static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1690{
1691 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001692 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001693 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001694 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001695
Hoonki Lee27511902013-03-14 18:19:06 -07001696
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001697#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001698 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1699 &pHddTdlsCtx->peerDiscoverTimer,
1700 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001701#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001702 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1703 &pHddTdlsCtx->peerUpdateTimer,
1704 pHddTdlsCtx->threshold_config.tx_period_t);
Hoonki Lee27511902013-03-14 18:19:06 -07001705}
1706
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001707void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
1708 eTDLSSupportMode tdls_mode,
1709 v_BOOL_t bUpdateLast)
Hoonki Lee27511902013-03-14 18:19:06 -07001710{
1711 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1712 VOS_STATUS status;
1713 hdd_adapter_t *pAdapter;
1714 tdlsCtx_t *pHddTdlsCtx;
1715
1716 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301717 if (NULL == pHddCtx)
1718 return;
Hoonki Lee27511902013-03-14 18:19:06 -07001719
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301720 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001721 {
1722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1723 "%s: unable to lock list", __func__);
1724 return;
1725 }
1726
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001727
1728 if (pHddCtx->tdls_mode == tdls_mode)
1729 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07001730 hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301731 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001732 return;
1733 }
1734
Hoonki Lee27511902013-03-14 18:19:06 -07001735 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1736
1737 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1738 {
1739 pAdapter = pAdapterNode->pAdapter;
Hoonki Leea6d49be2013-04-05 09:43:25 -07001740 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1741 if (NULL != pHddTdlsCtx)
Hoonki Lee27511902013-03-14 18:19:06 -07001742 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07001743 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
1744 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
1745 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
1746 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
1747 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07001748 }
1749 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1750 pAdapterNode = pNext;
1751 }
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001752 if(bUpdateLast)
1753 {
1754 pHddCtx->tdls_mode_last = tdls_mode;
1755 }
1756 else
1757 {
1758 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
1759 }
Hoonki Lee27511902013-03-14 18:19:06 -07001760 pHddCtx->tdls_mode = tdls_mode;
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001761
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301762 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -07001763}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001764
Hoonki Leed37cbb32013-04-20 00:31:14 -07001765static void wlan_hdd_tdls_pre_setup(struct work_struct *work)
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001766{
Hoonki Leed37cbb32013-04-20 00:31:14 -07001767 tdlsCtx_t *pHddTdlsCtx =
1768 container_of(work, tdlsCtx_t, implicit_setup);
1769 hdd_context_t *pHddCtx;
1770 hddTdlsPeer_t *curr_peer;
Hoonki Leefb8df672013-04-10 18:20:34 -07001771 hddTdlsPeer_t *temp_peer;
Hoonki Leed37cbb32013-04-20 00:31:14 -07001772 int status;
1773
1774 if (NULL == pHddTdlsCtx)
1775 return;
1776
1777 if (unlikely(TDLS_CTX_MAGIC != pHddTdlsCtx->magic))
1778 return;
1779
1780 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
Hoonki Leefb8df672013-04-10 18:20:34 -07001781
1782 if (NULL == pHddCtx)
1783 return;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001784
Hoonki Leed37cbb32013-04-20 00:31:14 -07001785 curr_peer = pHddTdlsCtx->curr_candidate;
1786
1787 if (NULL == curr_peer)
1788 return;
1789
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001790 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
1791 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001792 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001793 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1794 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001795
Hoonki Leefb8df672013-04-10 18:20:34 -07001796 temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, FALSE);
1797 if (NULL != temp_peer)
1798 {
1799 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored\n",
1800 __func__, MAC_ADDR_ARRAY(temp_peer->peerMac));
Hoonki Leed37cbb32013-04-20 00:31:14 -07001801 goto done;
Hoonki Leefb8df672013-04-10 18:20:34 -07001802 }
1803
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001804 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
1805 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
1806
Hoonki Leed37cbb32013-04-20 00:31:14 -07001807 status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy,
1808 pHddTdlsCtx->pAdapter->dev,
1809 curr_peer->peerMac);
1810
1811 if (0 != status)
1812 {
1813 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " discovery could not sent\n",
1814 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
1815 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
1816 curr_peer->link_status = eTDLS_LINK_IDLE;
1817 goto done;
1818 }
1819
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001820 pHddTdlsCtx->discovery_sent_cnt++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001821 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001822 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %lu timeout %lu msec",
1823 __func__, pHddTdlsCtx->discovery_sent_cnt,
1824 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001825
1826 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1827 &pHddTdlsCtx->peerDiscoveryTimeoutTimer,
1828 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001829
Hoonki Leed37cbb32013-04-20 00:31:14 -07001830done:
1831 pHddTdlsCtx->curr_candidate = NULL;
1832 pHddTdlsCtx->magic = 0;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001833 return;
1834}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001835
1836tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
1837{
1838 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1839 hdd_adapter_t *pAdapter = NULL;
1840 tdlsCtx_t *pHddTdlsCtx = NULL;
1841 VOS_STATUS status = 0;
1842 tANI_U32 count = 0;
1843
1844 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1845 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1846 {
1847 pAdapter = pAdapterNode->pAdapter;
1848
Hoonki Leea6d49be2013-04-05 09:43:25 -07001849 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1850 if (NULL != pHddTdlsCtx)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001851 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07001852 count = count + pHddTdlsCtx->discovery_sent_cnt;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001853 }
1854 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1855 pAdapterNode = pNext;
1856 }
1857 return count;
1858}
1859
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001860void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001861{
1862 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1863 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1864
1865 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
1866 return;
1867
1868 if ((0 == pHddCtx->connected_peer_count) &&
1869 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
1870 {
1871 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
1872 return;
1873 }
1874 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
1875 return;
1876}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001877
1878void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
1879{
1880 if (NULL == tdls_scan_ctx)
1881 return;
1882
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001883 tdls_scan_ctx->attempt = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -07001884 tdls_scan_ctx->reject = 0;
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001885 tdls_scan_ctx->magic = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001886 tdls_scan_ctx->scan_request = NULL;
1887 return;
1888}
1889
1890int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
1891 struct wiphy *wiphy,
1892#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1893 struct net_device *dev,
1894#endif
1895 struct cfg80211_scan_request *request)
1896{
1897 tdls_scan_context_t *scan_ctx;
1898
1899 if (NULL == pHddCtx )
1900 return -1;
1901
1902 scan_ctx = &pHddCtx->tdls_scan_ctxt;
1903
1904 scan_ctx->wiphy = wiphy;
1905#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1906 scan_ctx->dev = dev;
1907#endif
1908
1909 scan_ctx->scan_request = request;
1910 return 0;
1911}
1912
1913static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
1914{
1915 tdls_scan_context_t *scan_ctx =
1916 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
1917
1918 if (NULL == scan_ctx)
1919 return;
1920
1921 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
1922 return;
1923
1924 scan_ctx->attempt++;
1925
1926 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
1927#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1928 scan_ctx->dev,
1929#endif
1930 scan_ctx->scan_request);
1931}
1932
1933static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
1934 struct wiphy *wiphy,
1935#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1936 struct net_device *dev,
1937#endif
1938 struct cfg80211_scan_request *request,
1939 unsigned long delay)
1940{
1941 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
1942 {
1943#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1944 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
1945#else
1946 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
1947#endif
1948 pHddCtx->tdls_scan_ctxt.attempt = 0;
1949 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
1950 }
1951 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
1952
1953 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
1954}
1955
1956/* return negative = caller should stop and return error code immediately
1957 return 0 = caller should stop and return success immediately
1958 return 1 = caller can continue to scan
1959 */
1960int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
1961 struct wiphy *wiphy,
1962#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
1963 struct net_device *dev,
1964#endif
1965 struct cfg80211_scan_request *request)
1966{
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001967 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1968 u16 connectedTdlsPeers;
Hoonki Leefb8df672013-04-10 18:20:34 -07001969 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001970 unsigned long delay;
1971
1972 if (NULL == pHddCtx)
1973 return 0;
1974
1975 /* if tdls is not enabled, then continue scan */
1976 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
1977 return 1;
1978
Hoonki Leefb8df672013-04-10 18:20:34 -07001979 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0, TRUE);
1980 if (NULL != curr_peer)
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001981 {
Hoonki Leefb8df672013-04-10 18:20:34 -07001982 if (pHddCtx->tdls_scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT)
1983 {
1984 pHddCtx->tdls_scan_ctxt.reject = 0;
1985 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1986 "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle",
1987 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->tdls_scan_ctxt.reject);
1988
1989 wlan_hdd_tdls_set_peer_link_status (curr_peer, eTDLS_LINK_IDLE);
1990 return 1;
1991 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001992 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Leefb8df672013-04-10 18:20:34 -07001993 "%s: tdls in progress. scan rejected %d",
1994 __func__, pHddCtx->tdls_scan_ctxt.reject);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001995 return -EBUSY;
1996 }
1997
1998 /* tdls teardown is ongoing */
1999 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
2000 {
2001 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2002 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
2003 {
2004 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2005 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2006 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
2007 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
2008
2009 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2010#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2011 dev,
2012#endif
2013 request,
2014 msecs_to_jiffies(delay));
2015 /* scan should not continue */
2016 return 0;
2017 }
2018 /* no connected peer or max retry reached, scan continue */
2019 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2020 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
2021 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
2022 return 1;
2023 }
2024 /* while tdls is up, first time scan */
2025 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
2026 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
2027 {
2028 /* disable implicit trigger logic & tdls operatoin */
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002029 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002030 /* indicate the teardown all connected to peer */
2031 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2032 if (connectedTdlsPeers)
2033 {
2034 tANI_U8 staIdx;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002035 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002036
2037 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
2038 {
2039 if (pHddCtx->tdlsConnInfo[staIdx].staId)
2040 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002041 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002042 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
2043
2044#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leea6d49be2013-04-05 09:43:25 -07002045 curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
2046 if(curr_peer)
2047 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002048#endif
2049 }
2050 }
2051 /* schedule scan */
2052 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2053
2054 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2055 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
2056 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
2057 delay);
2058
2059 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2060#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2061 dev,
2062#endif
2063 request,
2064 msecs_to_jiffies(delay));
2065 /* scan should not continue */
2066 return 0;
2067 }
2068 /* no connected peer, scan continue */
2069 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2070 "%s: tdls_mode %d, and no tdls connection. scan allowed",
2071 __func__, pHddCtx->tdls_mode);
2072 }
2073 return 1;
2074}
2075
2076void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
2077{
2078 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002079
2080 if (NULL == pHddCtx)
2081 return;
2082
2083 /* free allocated memory at scan time */
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002084 wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002085
2086 /* if tdls was enabled before scan, re-enable tdls mode */
2087 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
2088 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
2089 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002090 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002091 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
2092
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002093 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002094 }
2095 wlan_hdd_tdls_check_bmps(pAdapter);
2096}
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002097
2098void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
2099 vos_timer_t *timer,
2100 v_U32_t expirationTime)
2101{
2102 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2103
2104 if (NULL == pHddStaCtx)
2105 return;
2106
2107 /* Check whether driver load unload is in progress */
2108 if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
2109 {
2110 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2111 "%s: Driver load/unload is in progress.", __func__);
2112 return;
2113 }
2114
2115 if (hdd_connIsConnected(pHddStaCtx))
2116 {
2117 vos_timer_stop(timer);
2118 vos_timer_start(timer, expirationTime);
2119 }
2120}
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002121void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
2122 hddTdlsPeer_t *curr_peer,
2123 tANI_U16 reason)
2124{
2125 if (NULL == pAdapter || NULL == curr_peer)
2126 return;
2127
2128 if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
2129 return;
2130
2131 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING);
2132 cfg80211_tdls_oper_request(pAdapter->dev,
2133 curr_peer->peerMac,
2134 NL80211_TDLS_TEARDOWN,
2135 reason,
2136 GFP_KERNEL);
2137}