blob: 35c6dc96fa70295c4f6ee01c7cf07dd711cb9022 [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Kiet Lamaa8e15a2014-02-11 23:30:06 -08002 * Copyright (c) 2012-2013 Qualcomm Atheros, Inc.
3 * All Rights Reserved.
4 * Qualcomm Atheros Confidential and Proprietary.
Gopichand Nakkala0c1331e2013-01-07 22:49:07 -08005 */
Kiran V1ccee932012-12-12 14:49:46 -08006/**========================================================================
7
8 \file wlan_hdd_tdls.c
9
Chilam NG571c65a2013-01-19 12:27:36 +053010 \brief WLAN Host Device Driver implementation for TDLS
Kiran V1ccee932012-12-12 14:49:46 -080011
Kiran V1ccee932012-12-12 14:49:46 -080012 ========================================================================*/
13
14#include <wlan_hdd_includes.h>
15#include <wlan_hdd_hostapd.h>
16#include <net/cfg80211.h>
17#include <linux/netdevice.h>
18#include <linux/skbuff.h>
Chilam NG571c65a2013-01-19 12:27:36 +053019#include <linux/list.h>
Kiran V1ccee932012-12-12 14:49:46 -080020#include <linux/etherdevice.h>
21#include <net/ieee80211_radiotap.h>
22#include "wlan_hdd_tdls.h"
Chilam NG571c65a2013-01-19 12:27:36 +053023#include "wlan_hdd_cfg80211.h"
Kiran V1ccee932012-12-12 14:49:46 -080024
Chilam NG571c65a2013-01-19 12:27:36 +053025
Gopichand Nakkala4327a152013-03-04 23:22:42 -080026static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
27static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
28static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +053029static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Sunil Dutt41de4e22013-11-14 18:09:02 +053030int wpa_tdls_is_allowed_force_peer(tdlsCtx_t *pHddTdlsCtx, u8 *mac);
Hoonki Leed37cbb32013-04-20 00:31:14 -070031#ifdef CONFIG_TDLS_IMPLICIT
32static void wlan_hdd_tdls_pre_setup(struct work_struct *work);
33#endif
Chilam NG571c65a2013-01-19 12:27:36 +053034
Hoonki Lee5a4b2172013-01-29 01:45:53 -080035#ifndef WLAN_FEATURE_TDLS_DEBUG
36#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
37#else
38#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN
39#endif
40
Hoonki Lee387663d2013-02-05 18:08:43 -080041static u8 wlan_hdd_tdls_hash_key (u8 *mac)
Hoonki Leef63df0d2013-01-16 19:29:14 -080042{
43 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -080044 u8 key = 0;
45
46 for (i = 0; i < 6; i++)
47 key ^= mac[i];
48
49 return key;
50}
51
Hoonki Leed37cbb32013-04-20 00:31:14 -070052#ifdef CONFIG_TDLS_IMPLICIT
53static void wlan_hdd_tdls_pre_setup_init_work(tdlsCtx_t * pHddTdlsCtx,
54 hddTdlsPeer_t *curr_candidate)
55{
56 if (TDLS_CTX_MAGIC != pHddTdlsCtx->magic)
57 {
58 pHddTdlsCtx->curr_candidate = curr_candidate;
59 pHddTdlsCtx->magic = TDLS_CTX_MAGIC;
60
Hoonki Leed37cbb32013-04-20 00:31:14 -070061 schedule_work(&pHddTdlsCtx->implicit_setup);
62 }
63}
64#endif
65
Gopichand Nakkala4327a152013-03-04 23:22:42 -080066static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx,
67 tANI_BOOLEAN mutexLock,
68 v_U32_t discoveryExpiry)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080069{
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080070 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053071 hdd_context_t *pHddCtx;
72
c_hpothu7f63e882013-10-02 19:13:35 +053073 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
74 {
75 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
76 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053077 return;
c_hpothu7f63e882013-10-02 19:13:35 +053078 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053079
80 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
81
c_hpothu7f63e882013-10-02 19:13:35 +053082 if(0 != (wlan_hdd_validate_context(pHddCtx)))
83 {
84 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
85 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053086 return;
c_hpothu7f63e882013-10-02 19:13:35 +053087 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080088
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080089 if ( mutexLock )
90 {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +053091 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080092 {
93 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +053094 FL("unable to lock list"));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080095 return;
96 }
97 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080098
Gopichand Nakkala4327a152013-03-04 23:22:42 -080099 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700100#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700101 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
102 &pHddTdlsCtx->peerDiscoverTimer,
103 discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700104#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700105 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
106 pHddTdlsCtx->ap_rssi);
107
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800108 if ( mutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530109 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800110
111 return;
112}
113
Hoonki Leed37cbb32013-04-20 00:31:14 -0700114#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Hoonki Lee387663d2013-02-05 18:08:43 -0800115static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
116{
117 int i;
118 struct list_head *head;
119 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530120 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800121 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530122 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800123 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800124 int discover_req_sent = 0;
125 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800126 tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800127
c_hpothu7f63e882013-10-02 19:13:35 +0530128 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
129 {
130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
131 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530132 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530133 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530134
135 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
136
c_hpothu7f63e882013-10-02 19:13:35 +0530137 if(0 != (wlan_hdd_validate_context(pHddCtx)))
138 {
139 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
140 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530141 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530142 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530143
144 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800145 {
146 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530147 FL("unable to lock list"));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800148 return;
149 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800150
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800151 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800152
Hoonki Lee387663d2013-02-05 18:08:43 -0800153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
154
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800155 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800156 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800157
Chilam NG571c65a2013-01-19 12:27:36 +0530158 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800159 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530160
Hoonki Lee387663d2013-02-05 18:08:43 -0800161 list_for_each (pos, head) {
162 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530163
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800164 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800165 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
166 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800167 curr_peer->discovery_processed,
168 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800169 curr_peer->tdls_support,
170 curr_peer->link_status,
171 curr_peer->discovery_attempt,
172 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800173
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800174 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
175 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530176
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800177 curr_peer->discovery_processed = 1;
178 discover_req_sent++;
179 pHddTdlsCtx->discovery_peer_cnt--;
180
181 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800182 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800183 (curr_peer->tx_pkt >=
184 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800185
186 if (curr_peer->discovery_attempt <
187 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800188 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
189 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800190 curr_peer->peerMac,
191 WLAN_TDLS_DISCOVERY_REQUEST,
192 1, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800193 curr_peer->discovery_attempt++;
194 }
195 else
196 {
197 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
198 "%s: Maximum Discovery retries reached", __func__);
199 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
200 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800201
202 }
203 }
Chilam NG571c65a2013-01-19 12:27:36 +0530204 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800205 else
206 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800207 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800208 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800209exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800210
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800211 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
212 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
213 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
214 pHddTdlsCtx->discovery_peer_cnt);
215 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800216 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800217 goto done;
218 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800219 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
220
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800221 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530222
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530223 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -0700224
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800225 /* Commenting out the following function as it was introducing
226 * a race condition when pHddTdlsCtx is deleted. Also , this
227 * function is consuming more time in the timer callback.
228 * RSSI based trigger needs to revisit this part of the code.
229 */
230
231 /*
232 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
233 */
Chilam NG571c65a2013-01-19 12:27:36 +0530234
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800235done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800236 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800237
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800238 if ( !doMutexLock )
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530239 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800240 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800241}
Hoonki Leed37cbb32013-04-20 00:31:14 -0700242#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530243
Hoonki Lee387663d2013-02-05 18:08:43 -0800244static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530245{
246 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800247 struct list_head *head;
248 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530249 hddTdlsPeer_t *curr_peer;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530250 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
251 hdd_context_t *pHddCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800252
c_hpothu7f63e882013-10-02 19:13:35 +0530253 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
254 {
255 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
256 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530257 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530258 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530259
260 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
261
c_hpothu7f63e882013-10-02 19:13:35 +0530262 if(0 != (wlan_hdd_validate_context(pHddCtx)))
263 {
264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
265 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530266 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530267 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530268
269 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800270 {
271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530272 FL("unable to lock list"));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800273 return;
274 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800275
Chilam NG571c65a2013-01-19 12:27:36 +0530276 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800277 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530278
Hoonki Lee387663d2013-02-05 18:08:43 -0800279 list_for_each (pos, head) {
280 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530281
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800282 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700283 "%s: " MAC_ADDRESS_STR " link_status %d"
284 " tdls_support %d", __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700285 curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800286
Chilam NG571c65a2013-01-19 12:27:36 +0530287 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800288 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700289 "tx %d, rx %d (thr.pkt %d/idle %d), rssi %d (thr.trig %d/hys %d/tear %d)",
290 curr_peer->tx_pkt, curr_peer->rx_pkt,
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800291 pHddTdlsCtx->threshold_config.tx_packet_n,
Hoonki Lee66b75f32013-04-16 18:30:07 -0700292 pHddTdlsCtx->threshold_config.idle_packet_n,
293 curr_peer->rssi,
294 pHddTdlsCtx->threshold_config.rssi_trigger_threshold,
295 pHddTdlsCtx->threshold_config.rssi_hysteresis,
296 pHddTdlsCtx->threshold_config.rssi_teardown_threshold);
Chilam Ng01120412013-02-19 18:32:21 -0800297
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800298 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
299 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530300
301 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
302 (FALSE == curr_peer->isForcedPeer)) {
303 continue;
304 }
305
Chilam NG571c65a2013-01-19 12:27:36 +0530306 if (curr_peer->tx_pkt >=
307 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800308
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800309 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800310 {
311
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700312 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "Tput trigger TDLS pre-setup");
Chilam NG571c65a2013-01-19 12:27:36 +0530313#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leed37cbb32013-04-20 00:31:14 -0700314 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530315#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800316 }
317 else
318 {
319 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800320 "%s: Maximum peer connected already! %d",
321 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800322 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800323 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530324 }
Hoonki Leefb8df672013-04-10 18:20:34 -0700325 }
326 else if (eTDLS_LINK_CONNECTED == curr_peer->link_status) {
Chilam Ng01120412013-02-19 18:32:21 -0800327 if ((tANI_S32)curr_peer->rssi <
328 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800329
Chilam Ng01120412013-02-19 18:32:21 -0800330 VOS_TRACE( VOS_MODULE_ID_HDD,
331 VOS_TRACE_LEVEL_WARN,
332 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
333 MAC_ADDR_ARRAY(curr_peer->peerMac));
334#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700335 wlan_hdd_tdls_indicate_teardown(pHddTdlsCtx->pAdapter,
336 curr_peer,
337 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Chilam Ng01120412013-02-19 18:32:21 -0800338#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800339 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530340 }
Chilam Ng01120412013-02-19 18:32:21 -0800341
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530342 /* Only teardown based on non zero idle packet threshold, to address a use
343 * case where this threshold does not get consider for TEAR DOWN.
344 */
345
346 if (( 0 != pHddTdlsCtx->threshold_config.idle_packet_n ) &&
347 ((curr_peer->tx_pkt <
Chilam Ng01120412013-02-19 18:32:21 -0800348 pHddTdlsCtx->threshold_config.idle_packet_n) &&
349 (curr_peer->rx_pkt <
Naresh Jayaramdb4514b2013-11-25 18:08:10 +0530350 pHddTdlsCtx->threshold_config.idle_packet_n))) {
Chilam Ng01120412013-02-19 18:32:21 -0800351 if (VOS_TIMER_STATE_RUNNING !=
352 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
353 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
354 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
355 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700356 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
357 &curr_peer->peerIdleTimer,
358 pHddTdlsCtx->threshold_config.idle_timeout_t);
Chilam Ng01120412013-02-19 18:32:21 -0800359 }
360 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800361 if (VOS_TIMER_STATE_RUNNING ==
362 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
364 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
365 MAC_ADDR_ARRAY(curr_peer->peerMac));
366 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800367 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800368 }
Chilam Ng01120412013-02-19 18:32:21 -0800369
Hoonki Leecdd8e962013-01-20 00:45:46 -0800370// if (curr_peer->rssi <
371// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
372// pHddTdlsCtx->ap_rssi)) {
373//
374//#ifdef CONFIG_TDLS_IMPLICIT
375// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
376// curr_peer->peerMac,
377// NL80211_TDLS_TEARDOWN, FALSE,
378// GFP_KERNEL);
379//#endif
380// }
Chilam NG571c65a2013-01-19 12:27:36 +0530381 }
Chilam Ng01120412013-02-19 18:32:21 -0800382 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
Sunil Dutt961ecbd2013-11-28 20:04:07 +0530383
384 if (pHddCtx->cfg_ini->fTDLSExternalControl &&
385 (FALSE == curr_peer->isForcedPeer)) {
386 continue;
387 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -0700388 if (!TDLS_IS_CONNECTED(curr_peer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800389 if (curr_peer->tx_pkt >=
390 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800391
Gopichand Nakkala062bcbd2013-03-29 18:14:47 -0700392 if (curr_peer->discovery_attempt++ <
Chilam Ng01120412013-02-19 18:32:21 -0800393 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700394 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "TDLS UNKNOWN discover ");
Hoonki Leed37cbb32013-04-20 00:31:14 -0700395#ifdef CONFIG_TDLS_IMPLICIT
396 wlan_hdd_tdls_pre_setup_init_work(pHddTdlsCtx, curr_peer);
397#endif
Chilam Ng01120412013-02-19 18:32:21 -0800398 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800399 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800400 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800401 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800402 curr_peer->link_status = eTDLS_LINK_IDLE;
403 }
Chilam Ng01120412013-02-19 18:32:21 -0800404 }
405 }
Chilam NG571c65a2013-01-19 12:27:36 +0530406 }
407
Hoonki Leecdd8e962013-01-20 00:45:46 -0800408next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530409 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800410 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800411 }
Chilam NG571c65a2013-01-19 12:27:36 +0530412 }
413
Gopichand Nakkala3046fc92013-03-23 13:56:43 -0700414 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
415 &pHddTdlsCtx->peerUpdateTimer,
416 pHddTdlsCtx->threshold_config.tx_period_t);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530417 mutex_unlock(&pHddCtx->tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530418}
419
Chilam Ng1279e232013-01-25 15:06:52 -0800420static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
421{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800422#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800423 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530424 tdlsCtx_t *pHddTdlsCtx;
425 hdd_context_t *pHddCtx;
Chilam Ng1279e232013-01-25 15:06:52 -0800426
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700427 if (NULL == curr_peer)
428 {
429 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530430 FL("Invalid tdls idle timer expired"));
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700431 return;
432 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530433 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
434
435 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530436 {
437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
438 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530439 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530440 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530441
442 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
443
c_hpothu7f63e882013-10-02 19:13:35 +0530444 if(0 != (wlan_hdd_validate_context(pHddCtx)))
445 {
446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
447 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530448 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530449 }
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700450
451 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Arif Hussain6d2a3322013-11-17 19:50:10 -0800452 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " tx_pkt: %d, rx_pkt: %d, idle_packet_n: %d",
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700453 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac),
454 curr_peer->tx_pkt,
455 curr_peer->rx_pkt,
456 curr_peer->pHddTdlsCtx->threshold_config.idle_packet_n);
457
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530458 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800459 {
460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530461 FL("unable to lock list"));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800462 return;
463 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800464
Rajesh Chauhan1ace6002013-04-18 18:08:21 -0700465 /* Check tx/rx statistics on this tdls link for recent activities and
466 * then decide whether to tear down the link or keep it.
467 */
468 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))
469 {
470 /* this tdls link got back to normal, so keep it */
471 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
472 "%s: tdls link to " MAC_ADDRESS_STR " back to normal, will stay",
473 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
474 }
475 else
476 {
477 /* this tdls link needs to get torn down */
478 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
479 "%s: trigger tdls link to " MAC_ADDRESS_STR " down",
480 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
481
482 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter,
483 curr_peer,
484 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
485 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530486 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800487#endif
488}
489
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700490static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
491{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700492 int i;
493 struct list_head *head;
494 hddTdlsPeer_t *tmp;
495 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700496 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530497 hdd_context_t *pHddCtx;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700498
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530499 pHddTdlsCtx = (tdlsCtx_t *)userData;
500
501 if ((NULL == pHddTdlsCtx) || (NULL == pHddTdlsCtx->pAdapter) )
c_hpothu7f63e882013-10-02 19:13:35 +0530502 {
503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
504 FL(" pHddTdlsCtx or pAdapter points to NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530505 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530506 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530507
508 pHddCtx = WLAN_HDD_GET_CTX( pHddTdlsCtx->pAdapter );
509
c_hpothu7f63e882013-10-02 19:13:35 +0530510 if(0 != (wlan_hdd_validate_context(pHddCtx)))
511 {
512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
513 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530514 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530515 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530516
517 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700518 {
519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530520 FL("unable to lock list"));
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700521 return ;
522 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700523
524 for (i = 0; i < 256; i++) {
525 head = &pHddTdlsCtx->peer_list[i];
526 list_for_each_safe (pos, q, head) {
527 tmp = list_entry(pos, hddTdlsPeer_t, node);
528 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
529 {
530 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
531 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
532 MAC_ADDR_ARRAY(tmp->peerMac));
533 tmp->link_status = eTDLS_LINK_IDLE;
534 }
535 }
536 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700537
538 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700539 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700540
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530541 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700542
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700543 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
544
545 return;
546}
547
Hoonki Lee14621352013-04-16 17:51:19 -0700548static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
549{
550 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
551 tdlsCtx_t *pHddTdlsCtx;
552
553 if ( NULL == curr_peer )
c_hpothu7f63e882013-10-02 19:13:35 +0530554 {
555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
556 FL("curr_peer is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700557 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530558 }
Hoonki Lee14621352013-04-16 17:51:19 -0700559
560 pHddTdlsCtx = curr_peer->pHddTdlsCtx;
561
562 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +0530563 {
564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
565 FL("pHddTdlsCtx is NULL"));
Hoonki Lee14621352013-04-16 17:51:19 -0700566 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530567 }
Hoonki Lee14621352013-04-16 17:51:19 -0700568
569 WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext,
570 (v_U8_t *)&curr_peer->staId);
571}
572
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800573static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800574{
575 int i;
576 struct list_head *head;
577 hddTdlsPeer_t *tmp;
578 struct list_head *pos, *q;
579
c_hpothu7f63e882013-10-02 19:13:35 +0530580 if (NULL == pHddTdlsCtx)
581 {
582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
583 FL("pHddTdlsCtx is NULL"));
584 return;
585 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800586
587 for (i = 0; i < 256; i++) {
588 head = &pHddTdlsCtx->peer_list[i];
589 list_for_each_safe (pos, q, head) {
590 tmp = list_entry(pos, hddTdlsPeer_t, node);
591 list_del(pos);
592 vos_mem_free(tmp);
Srinivas Girigowda8d2348f2013-12-12 12:14:15 -0800593 tmp = NULL;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800594 }
595 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800596}
597
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700598static void wlan_hdd_tdls_schedule_scan(struct work_struct *work)
599{
600 tdls_scan_context_t *scan_ctx =
601 container_of(work, tdls_scan_context_t, tdls_scan_work.work);
602
603 if (NULL == scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +0530604 {
605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
606 FL("scan_ctx is NULL"));
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700607 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530608 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700609
610 if (unlikely(TDLS_CTX_MAGIC != scan_ctx->magic))
611 return;
612
613 scan_ctx->attempt++;
614
615 wlan_hdd_cfg80211_scan(scan_ctx->wiphy,
616#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
617 scan_ctx->dev,
618#endif
619 scan_ctx->scan_request);
620}
621
622
Hoonki Lee27511902013-03-14 18:19:06 -0700623int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800624{
Chilam Ng01120412013-02-19 18:32:21 -0800625 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700626 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800627 int i;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800628 v_U8_t staIdx;
Chilam Ng01120412013-02-19 18:32:21 -0800629
Sunil Dutt66485cb2013-12-19 19:05:03 +0530630 if (NULL == pHddCtx)
631 return -1;
632
633 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
634 {
635 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
636 "%s: unable to lock list", __func__);
637 return -1;
638 }
639
Hoonki Lee27511902013-03-14 18:19:06 -0700640 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
641 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
642 {
643 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
644 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
645 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
646 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
647 sme_IsFeatureSupportedByFW(TDLS));
Sunil Dutt66485cb2013-12-19 19:05:03 +0530648 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -0700649 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800650 }
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530651 /* TDLS is supported only in STA / P2P Client modes,
652 * hence the check for TDLS support in a specific Device mode.
653 * Do not return a failure rather do not continue further
654 * with the initialization as tdls_init would be called
655 * during the open adapter for a p2p interface at which point
656 * the device mode would be a P2P_DEVICE. The point here is to
657 * continue initialization for STA / P2P Client modes.
658 * TDLS exit also check for the device mode for clean up hence
659 * there is no issue even if success is returned.
660 */
661 if (0 == WLAN_HDD_IS_TDLS_SUPPORTED_ADAPTER(pAdapter))
662 {
Sunil Dutt66485cb2013-12-19 19:05:03 +0530663 mutex_unlock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530664 return 0;
665 }
666 /* Check for the valid pHddTdlsCtx. If valid do not further
667 * allocate the memory, rather continue with the initialization.
668 * If tdls_initialization would get reinvoked without tdls_exit
669 * getting invoked (SSR) there is no point to further proceed
670 * with the memory allocations.
671 */
672 if (NULL == pAdapter->sessionCtx.station.pHddTdlsCtx)
673 {
674 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800675
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530676 if (NULL == pHddTdlsCtx) {
677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
678 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
Sunil Dutt66485cb2013-12-19 19:05:03 +0530679 mutex_unlock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530680 return -1;
681 }
682 /* initialize TDLS pAdater context */
683 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
684#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
685 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
686 VOS_TIMER_TYPE_SW,
687 wlan_hdd_tdls_discover_peer_cb,
688 pHddTdlsCtx);
689#endif
Hoonki Lee27511902013-03-14 18:19:06 -0700690
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530691 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
692 VOS_TIMER_TYPE_SW,
693 wlan_hdd_tdls_update_peer_cb,
694 pHddTdlsCtx);
695 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
696 VOS_TIMER_TYPE_SW,
697 wlan_hdd_tdls_discovery_timeout_peer_cb,
698 pHddTdlsCtx);
699
700 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700701 }
702
Madan Mohan Koyyalamudi81746922013-07-17 14:38:51 +0530703 pHddTdlsCtx = pAdapter->sessionCtx.station.pHddTdlsCtx;
Hoonki Lee27511902013-03-14 18:19:06 -0700704
705 /* initialize TDLS global context */
706 pHddCtx->connected_peer_count = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700707 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700708
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700709 pHddCtx->tdls_scan_ctxt.magic = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -0700710 pHddCtx->tdls_scan_ctxt.attempt = 0;
711 pHddCtx->tdls_scan_ctxt.reject = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700712 pHddCtx->tdls_scan_ctxt.scan_request = NULL;
713
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800714 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
715 {
716 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
717 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
718 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
719 sizeof(v_MACADDR_t)) ;
Chilam Ng01120412013-02-19 18:32:21 -0800720 }
721
Hoonki Lee27511902013-03-14 18:19:06 -0700722 pHddTdlsCtx->pAdapter = pAdapter;
723
724 for (i = 0; i < 256; i++)
725 {
726 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
727 }
728
Hoonki Leed37cbb32013-04-20 00:31:14 -0700729 pHddTdlsCtx->curr_candidate = NULL;
730 pHddTdlsCtx->magic = 0;
731
Hoonki Lee27511902013-03-14 18:19:06 -0700732 /* remember configuration even if it is not used right now. it could be used later */
733 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
734 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
735 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
736 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
737 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
738 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
739 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
740 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
741 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530742
Chilam Ng01120412013-02-19 18:32:21 -0800743 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
Hoonki Lee387663d2013-02-05 18:08:43 -0800744 {
Chilam Ng01120412013-02-19 18:32:21 -0800745 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
Hoonki Leebf870f32013-01-19 15:53:30 +0530746 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Leebf870f32013-01-19 15:53:30 +0530747 }
Hoonki Lee27511902013-03-14 18:19:06 -0700748 else
749 {
750 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
Hoonki Lee27511902013-03-14 18:19:06 -0700751 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700752 INIT_WORK(&pHddTdlsCtx->implicit_setup, wlan_hdd_tdls_pre_setup);
753 INIT_DELAYED_WORK(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, wlan_hdd_tdls_schedule_scan);
Sunil Dutt66485cb2013-12-19 19:05:03 +0530754 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -0700755
756 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530757}
758
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800759void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530760{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800761 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700762 hdd_context_t *pHddCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800763
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530764 /*
765 * NOTE: The Callers of this function should ensure to acquire the
766 * tdls_lock to avoid any concurrent access to the Adapter.
767 */
768
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530769 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
c_hpothu7f63e882013-10-02 19:13:35 +0530770 if(0 != (wlan_hdd_validate_context(pHddCtx)))
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530771 {
c_hpothu7f63e882013-10-02 19:13:35 +0530772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
773 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530774 return;
775 }
776
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800777 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800778 if (NULL == pHddTdlsCtx)
779 {
c_hpothu7f63e882013-10-02 19:13:35 +0530780 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
781 FL("pHddTdlsCtx is NULL"));
Hoonki Leebfee0342013-01-21 16:43:45 -0800782 return;
783 }
Sameer Thalappilbee426e2013-10-30 10:30:30 -0700784#ifdef WLAN_OPEN_SOURCE
785 cancel_work_sync(&pHddTdlsCtx->implicit_setup);
786 cancel_delayed_work_sync(&pHddCtx->tdls_scan_ctxt.tdls_scan_work);
787#endif
Hoonki Leebfee0342013-01-21 16:43:45 -0800788
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800789 /* must stop timer here before freeing peer list, because peerIdleTimer is
790 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800791 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
792 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800793
Hoonki Lee93e67ff2013-03-19 15:49:25 -0700794 wlan_hdd_tdls_free_scan_request(&pHddCtx->tdls_scan_ctxt);
795
Chilam Nga75d8b62013-01-29 01:35:59 -0800796 vos_mem_free(pHddTdlsCtx);
797 pHddTdlsCtx = NULL;
Chilam NG571c65a2013-01-19 12:27:36 +0530798}
799
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530800/* stop all monitoring timers per Adapter */
801static void wlan_hdd_tdls_monitor_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800802{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700803#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800804 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700805#endif
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800806 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700807 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530808}
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800809
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530810/* stop all per peer timers */
811static void wlan_hdd_tdls_peer_timers_stop(tdlsCtx_t *pHddTdlsCtx)
812{
813 int i;
814 struct list_head *head;
815 struct list_head *pos;
816 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800817 for (i = 0; i < 256; i++)
818 {
819 head = &pHddTdlsCtx->peer_list[i];
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800820 list_for_each (pos, head) {
821 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800822 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800823 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800824 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800825 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800826 vos_timer_stop ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700827 vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800828 }
829 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800830}
831
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530832/* stop all the tdls timers running */
833static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800834{
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530835 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
836 wlan_hdd_tdls_peer_timers_stop(pHddTdlsCtx);
837}
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800838
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530839static void wlan_hdd_tdls_monitor_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
840{
Hoonki Leed37cbb32013-04-20 00:31:14 -0700841#ifdef TDLS_USE_SEPARATE_DISCOVERY_TIMER
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800842 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
843 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
Hoonki Leed37cbb32013-04-20 00:31:14 -0700844#endif
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800845 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
846 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700847 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
848 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530849}
850/*Free all the timers related to the TDLS peer */
851static void wlan_hdd_tdls_peer_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
852{
853 int i;
854 struct list_head *head;
855 struct list_head *pos;
856 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800857 for (i = 0; i < 256; i++)
858 {
859 head = &pHddTdlsCtx->peer_list[i];
860
861 list_for_each (pos, head) {
862 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
863
864 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800865 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800866 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800867 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800868 vos_timer_stop ( &curr_peer->peerIdleTimer );
869 vos_timer_destroy ( &curr_peer->peerIdleTimer );
Hoonki Lee14621352013-04-16 17:51:19 -0700870 vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
871 vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800872 }
873 }
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +0530874
875}
876
877/* destroy all the tdls timers running */
878static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
879{
880 wlan_hdd_tdls_monitor_timers_destroy(pHddTdlsCtx);
881 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800882}
883
Hoonki Lee387663d2013-02-05 18:08:43 -0800884/* if mac address exist, return pointer
885 if mac address doesn't exist, create a list and add, return pointer
886 return NULL if fails to get new mac address
887*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800888hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530889{
Hoonki Lee387663d2013-02-05 18:08:43 -0800890 struct list_head *head;
891 hddTdlsPeer_t *peer;
892 u8 key;
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700893 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530894 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
895
c_hpothu7f63e882013-10-02 19:13:35 +0530896 if(0 != (wlan_hdd_validate_context(pHddCtx)))
897 {
898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
899 FL("pHddCtx is not valid"));
900 return 0;
901 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800902
Hoonki Lee387663d2013-02-05 18:08:43 -0800903 /* if already there, just update */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530904 peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -0800905 if (peer != NULL)
906 {
907 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530908 }
909
Hoonki Lee387663d2013-02-05 18:08:43 -0800910 /* not found, allocate and add the list */
911 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
912 if (NULL == peer) {
913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
914 return NULL;
915 }
Chilam NG571c65a2013-01-19 12:27:36 +0530916
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530917 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -0800918 {
919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +0530920 FL("unable to lock list"));
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700921 vos_mem_free(peer);
Hoonki Lee387663d2013-02-05 18:08:43 -0800922 return NULL;
923 }
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700924 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
925
926 if (NULL == pHddTdlsCtx)
927 {
c_hpothu7f63e882013-10-02 19:13:35 +0530928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
929 FL("pHddTdlsCtx is NULL"));
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700930 vos_mem_free(peer);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530931 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -0700932 return NULL;
933 }
934
935 key = wlan_hdd_tdls_hash_key(mac);
936 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530937
Hoonki Lee387663d2013-02-05 18:08:43 -0800938 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
939 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800940 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800941
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800942 vos_timer_init(&peer->peerIdleTimer,
943 VOS_TIMER_TYPE_SW,
944 wlan_hdd_tdls_idle_cb,
945 peer);
946
Hoonki Lee14621352013-04-16 17:51:19 -0700947 vos_timer_init(&peer->initiatorWaitTimeoutTimer,
948 VOS_TIMER_TYPE_SW,
949 wlan_hdd_tdls_initiator_wait_cb,
950 peer);
951
Hoonki Lee387663d2013-02-05 18:08:43 -0800952 list_add_tail(&peer->node, head);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +0530953 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800954
955 return peer;
956}
957
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700958int wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
Hoonki Lee27511902013-03-14 18:19:06 -0700959 u8* mac,
960 tTDLSCapType cap)
961{
962 hddTdlsPeer_t *curr_peer;
963
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700964 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee27511902013-03-14 18:19:06 -0700965 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +0530966 {
967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
968 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700969 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +0530970 }
Hoonki Lee27511902013-03-14 18:19:06 -0700971
972 curr_peer->tdls_support = cap;
973
Gopichand Nakkala34d1b062013-03-19 15:28:33 -0700974 return 0;
Hoonki Lee27511902013-03-14 18:19:06 -0700975}
976
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800977void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800978{
979 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +0530980 {
981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
982 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800983 return;
c_hpothu7f63e882013-10-02 19:13:35 +0530984 }
Hoonki Lee387663d2013-02-05 18:08:43 -0800985
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800986 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800987 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530988
989 curr_peer->link_status = status;
990
Chilam NG571c65a2013-01-19 12:27:36 +0530991}
992
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800993void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
994 u8* mac,
995 tTDLSLinkStatus linkStatus)
996{
997 hddTdlsPeer_t *curr_peer;
998
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +0530999 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001000 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301001 {
1002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1003 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001004 return;
c_hpothu7f63e882013-10-02 19:13:35 +05301005 }
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001006
1007 curr_peer->link_status= linkStatus;
1008
1009 return;
1010}
1011
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001012int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301013{
1014 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001015 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301016 hdd_context_t *pHddCtx;
1017
1018 if ( NULL == pHddTdlsCtx )
c_hpothu7f63e882013-10-02 19:13:35 +05301019 {
1020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1021 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301022 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301023 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301024
1025 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1026
c_hpothu7f63e882013-10-02 19:13:35 +05301027 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1028 {
1029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1030 FL("pHddCtx is not valid"));
1031 return 0;
1032 }
Chilam NG571c65a2013-01-19 12:27:36 +05301033
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001034 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001035
1036 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05301037 {
1038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1039 FL("curr_peer is NULL"));
Hoonki Lee387663d2013-02-05 18:08:43 -08001040 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301041 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001042
1043 if (pHddTdlsCtx->discovery_sent_cnt)
1044 pHddTdlsCtx->discovery_sent_cnt--;
1045
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301046 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1047 {
1048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301049 FL("unable to lock list"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301050 return -1;
1051 }
1052
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001053 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301054
1055 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001056 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001057 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001058 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001059 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001060
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001061 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001062 "Discovery(%u) Response from " MAC_ADDRESS_STR " link_status %d",
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001063 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
1064 curr_peer->link_status);
1065
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001066 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001067 {
Shailender Karmuchi13c0d082013-03-26 14:41:39 -07001068 /* Since we are here, it means Throughput threshold is alredy met. Make sure RSSI
1069 threshold is also met before setting up TDLS link*/
1070 if ((tANI_S32) curr_peer->rssi > (tANI_S32) pHddTdlsCtx->threshold_config.rssi_trigger_threshold)
1071 {
1072 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
1073 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1074 "Rssi Threshold met: "MAC_ADDRESS_STR" rssi = %d threshold= %d" ,
1075 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1076 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
1077 cfg80211_tdls_oper_request(pAdapter->dev, curr_peer->peerMac, NL80211_TDLS_SETUP, FALSE, GFP_KERNEL);
1078 }
1079 else
1080 {
1081 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1082 "Rssi Threshold not met: "MAC_ADDRESS_STR" rssi = %d threshold = %d ",
1083 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->rssi,
1084 pHddTdlsCtx->threshold_config.rssi_trigger_threshold);
1085 curr_peer->link_status = eTDLS_LINK_IDLE;
1086 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001087 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001088 else
1089 {
1090 wlan_hdd_tdls_check_bmps(pAdapter);
1091 }
Chilam NG571c65a2013-01-19 12:27:36 +05301092
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001093 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -08001094 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301095}
1096
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301097int wlan_hdd_tdls_set_peer_caps(hdd_adapter_t *pAdapter,
1098 u8 *mac,
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301099 tCsrStaParams *StaParams,
1100 tANI_BOOLEAN isBufSta,
1101 tANI_BOOLEAN isOffChannelSupported)
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301102{
1103 hddTdlsPeer_t *curr_peer;
1104
1105 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1106 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301107 {
1108 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1109 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301110 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301111 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301112
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301113 curr_peer->uapsdQueues = StaParams->uapsd_queues;
1114 curr_peer->maxSp = StaParams->max_sp;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301115 curr_peer->isBufSta = isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301116 curr_peer->isOffChannelSupported = isOffChannelSupported;
1117
1118 vos_mem_copy(curr_peer->supported_channels,
1119 StaParams->supported_channels,
1120 StaParams->supported_channels_len);
1121
1122 curr_peer->supported_channels_len =
1123 StaParams->supported_channels_len;
1124
1125 vos_mem_copy(curr_peer->supported_oper_classes,
1126 StaParams->supported_oper_classes,
1127 StaParams->supported_oper_classes_len);
1128
1129 curr_peer->supported_oper_classes_len =
1130 StaParams->supported_oper_classes_len;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301131 return 0;
1132}
1133
1134int wlan_hdd_tdls_get_link_establish_params(hdd_adapter_t *pAdapter, u8 *mac,
1135 tCsrTdlsLinkEstablishParams* tdlsLinkEstablishParams)
1136{
1137 hddTdlsPeer_t *curr_peer;
1138
1139 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
1140 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301141 {
1142 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1143 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301144 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301145 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301146
1147 tdlsLinkEstablishParams->isResponder = curr_peer->is_responder;
1148 tdlsLinkEstablishParams->uapsdQueues = curr_peer->uapsdQueues;
1149 tdlsLinkEstablishParams->maxSp = curr_peer->maxSp;
1150 tdlsLinkEstablishParams->isBufSta = curr_peer->isBufSta;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05301151 tdlsLinkEstablishParams->isOffChannelSupported =
1152 curr_peer->isOffChannelSupported;
1153
1154 vos_mem_copy(tdlsLinkEstablishParams->supportedChannels,
1155 curr_peer->supported_channels,
1156 curr_peer->supported_channels_len);
1157
1158 tdlsLinkEstablishParams->supportedChannelsLen =
1159 curr_peer->supported_channels_len;
1160
1161 vos_mem_copy(tdlsLinkEstablishParams->supportedOperClasses,
1162 curr_peer->supported_oper_classes,
1163 curr_peer->supported_oper_classes_len);
1164
1165 tdlsLinkEstablishParams->supportedOperClassesLen =
1166 curr_peer->supported_oper_classes_len;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05301167 return 0;
1168}
1169
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001170int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +05301171{
1172 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +05301173
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301174 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Hoonki Lee387663d2013-02-05 18:08:43 -08001175 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301176 {
1177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1178 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001179 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301180 }
Chilam NG571c65a2013-01-19 12:27:36 +05301181
1182 curr_peer->rssi = rxRssi;
1183
Hoonki Lee387663d2013-02-05 18:08:43 -08001184 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +05301185}
1186
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001187int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -08001188{
1189 hddTdlsPeer_t *curr_peer;
1190
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001191 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001192 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301193 {
1194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1195 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001196 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301197 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001198
1199 curr_peer->is_responder = responder;
1200
1201 return 0;
1202}
1203
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001204int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -08001205{
1206 hddTdlsPeer_t *curr_peer;
1207
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301208 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001209 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301210 {
1211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1212 "%s: curr_peer is NULL", __func__);
Hoonki Leea34dd892013-02-05 22:56:02 -08001213 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301214 }
Hoonki Leea34dd892013-02-05 22:56:02 -08001215
1216 return (curr_peer->is_responder);
1217}
1218
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001219int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001220{
1221 hddTdlsPeer_t *curr_peer;
1222
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001223 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001224 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301225 {
1226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1227 "%s: curr_peer is NULL", __func__);
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001228 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301229 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -08001230
1231 curr_peer->signature = uSignature;
1232
1233 return 0;
1234}
1235
Hoonki Leea34dd892013-02-05 22:56:02 -08001236
Hoonki Lee387663d2013-02-05 18:08:43 -08001237void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +05301238{
Chilam NG571c65a2013-01-19 12:27:36 +05301239 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +05301240}
1241
Hoonki Lee387663d2013-02-05 18:08:43 -08001242void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -08001243{
Chilam Ng1279e232013-01-25 15:06:52 -08001244 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -08001245}
1246
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001247int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +05301248{
Hoonki Lee387663d2013-02-05 18:08:43 -08001249 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001250 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +05301251
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001252 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
1253 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -08001254
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001255 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001256 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301257 {
1258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1259 "%s: curr_peer is NULL", __func__);
Chilam NG571c65a2013-01-19 12:27:36 +05301260 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301261 }
Chilam NG571c65a2013-01-19 12:27:36 +05301262
Chilam Ng1279e232013-01-25 15:06:52 -08001263 if (tx)
1264 curr_peer->tx_pkt++;
1265 else
1266 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +05301267
Chilam NG571c65a2013-01-19 12:27:36 +05301268 return 0;
1269}
1270
Hoonki Lee27511902013-03-14 18:19:06 -07001271static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
1272{
1273 if (config->tdls > 2)
1274 {
1275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
1276 return -1;
1277 }
1278 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
1279 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
1280 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001281 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%ld>", __func__, config->tx_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001282 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
1283 return -1;
1284 }
1285 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
1286 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
1287 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001288 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%ld>", __func__, config->tx_packet_n,
Hoonki Lee27511902013-03-14 18:19:06 -07001289 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
1290 return -1;
1291 }
1292 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
1293 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
1294 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07001295 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%ld>", __func__, config->discovery_period_t,
Hoonki Lee27511902013-03-14 18:19:06 -07001296 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
1297 return -1;
1298 }
1299 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
1300 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
1301 {
1302 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
1303 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
1304 return -1;
1305 }
1306 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
1307 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
1308 {
1309 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
1310 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
1311 return -1;
1312 }
1313 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
1314 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
1315 {
1316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
1317 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
1318 return -1;
1319 }
1320 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
1321 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
1322 {
1323 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
1324 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
1325 return -1;
1326 }
1327 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
1328 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
1329 {
1330 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
1331 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
1332 return -1;
1333 }
1334 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
1335 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
1338 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
1339 return -1;
1340 }
1341 return 0;
1342}
1343
Chilam Ng01120412013-02-19 18:32:21 -08001344int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +05301345{
Chilam Ng01120412013-02-19 18:32:21 -08001346 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1347 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001348 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -07001349 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -08001350
Hoonki Lee27511902013-03-14 18:19:06 -07001351 if (NULL == pHddTdlsCtx)
1352 {
c_hpothu7f63e882013-10-02 19:13:35 +05301353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS not enabled!"));
Hoonki Lee27511902013-03-14 18:19:06 -07001354 return -1;
Chilam Ng01120412013-02-19 18:32:21 -08001355 }
Chilam NG571c65a2013-01-19 12:27:36 +05301356
Hoonki Lee27511902013-03-14 18:19:06 -07001357 if (wlan_hdd_tdls_check_config(config) != 0)
1358 {
1359 return -1;
1360 }
1361
1362 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1363 req_tdls_mode = config->tdls + 1;
1364 if (pHddCtx->tdls_mode == req_tdls_mode)
1365 {
1366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1367 return -1;
1368 }
1369
1370 /* copy the configuration only when given tdls mode is implicit trigger enable */
1371 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1372 {
Chilam Ng01120412013-02-19 18:32:21 -08001373 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1374 }
Chilam NG571c65a2013-01-19 12:27:36 +05301375
Chilam Ng01120412013-02-19 18:32:21 -08001376 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1377 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1378 config->tdls,
1379 config->tx_period_t,
1380 config->tx_packet_n,
1381 config->discovery_period_t,
1382 config->discovery_tries_n,
1383 config->idle_timeout_t,
1384 config->idle_packet_n,
1385 config->rssi_hysteresis,
1386 config->rssi_trigger_threshold,
1387 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301388
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07001389 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode, TRUE);
Chilam Ng01120412013-02-19 18:32:21 -08001390
Chilam NG571c65a2013-01-19 12:27:36 +05301391 return 0;
1392}
1393
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001394int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001395{
Hoonki Lee387663d2013-02-05 18:08:43 -08001396 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001397
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001398 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001399 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301400 {
1401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1402 "%s: curr_peer is NULL", __func__);
Chilam NG571c65a2013-01-19 12:27:36 +05301403 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301404 }
Chilam NG571c65a2013-01-19 12:27:36 +05301405
Hoonki Lee387663d2013-02-05 18:08:43 -08001406 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301407
1408 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001409}
1410
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301411int wlan_hdd_tdls_set_force_peer(hdd_adapter_t *pAdapter, u8 *mac,
1412 tANI_BOOLEAN forcePeer)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301413{
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301414 hddTdlsPeer_t *curr_peer;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301415 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1416
1417 if ((NULL == pHddCtx)) return -1;
1418
1419 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1420 {
1421 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1422 "%s: unable to lock list", __func__);
1423 return -1;
1424 }
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301425 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
1426 if (curr_peer == NULL)
Sunil Dutt41de4e22013-11-14 18:09:02 +05301427 goto error;
Naresh Jayaram937abdf2013-11-26 19:50:25 +05301428 curr_peer->isForcedPeer = forcePeer;
Naresh Jayaramca7bc3a2014-02-04 23:03:04 +05301429
1430 mutex_unlock(&pHddCtx->tdls_lock);
1431 return 0;
Sunil Dutt41de4e22013-11-14 18:09:02 +05301432error:
1433 mutex_unlock(&pHddCtx->tdls_lock);
1434 return -1;
1435}
1436
Hoonki Lee387663d2013-02-05 18:08:43 -08001437/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1438 otherwise, it returns NULL
1439*/
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301440hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac,
1441 tANI_BOOLEAN mutexLock)
Kiran V1ccee932012-12-12 14:49:46 -08001442{
Hoonki Lee387663d2013-02-05 18:08:43 -08001443 u8 key;
1444 struct list_head *pos;
1445 struct list_head *head;
1446 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001447 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301448 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee387663d2013-02-05 18:08:43 -08001449
c_hpothu7f63e882013-10-02 19:13:35 +05301450 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1451 {
1452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1453 FL("pHddCtx is not valid"));
1454 return 0;
1455 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001456
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301457 if ( mutexLock )
Hoonki Lee387663d2013-02-05 18:08:43 -08001458 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301459 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1460 {
1461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301462 FL("unable to lock list"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301463 return NULL;
1464 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001465 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001466 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001467 if (NULL == pHddTdlsCtx)
1468 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301469 if ( mutexLock )
1470 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001471 return NULL;
1472 }
1473
1474 key = wlan_hdd_tdls_hash_key(mac);
1475
1476 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001477
1478 list_for_each(pos, head) {
1479 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1480 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1481 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1482 "findTdlsPeer: found staId %d", curr_peer->staId);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301483 if ( mutexLock )
1484 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001485 return curr_peer;
1486 }
1487 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301488 if ( mutexLock )
1489 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001490 return NULL;
1491}
1492
Hoonki Leea6d49be2013-04-05 09:43:25 -07001493hddTdlsPeer_t *wlan_hdd_tdls_find_all_peer(hdd_context_t *pHddCtx, u8 *mac)
1494{
1495 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1496 hdd_adapter_t *pAdapter = NULL;
1497 tdlsCtx_t *pHddTdlsCtx = NULL;
1498 hddTdlsPeer_t *curr_peer= NULL;
1499 VOS_STATUS status = 0;
1500
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301501 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1502 {
1503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301504 FL("unable to lock list"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301505 return NULL;
1506 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07001507 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1508 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1509 {
1510 pAdapter = pAdapterNode->pAdapter;
1511
1512 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1513 if (NULL != pHddTdlsCtx)
1514 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301515 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001516 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301517 {
1518 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001519 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301520 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07001521 }
1522 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1523 pAdapterNode = pNext;
1524 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301525 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leea6d49be2013-04-05 09:43:25 -07001526 return curr_peer;
1527}
1528
1529
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001530int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001531{
Chilam Ng01120412013-02-19 18:32:21 -08001532 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301533 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001534
Chilam Ng01120412013-02-19 18:32:21 -08001535 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1536
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001537 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001538 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301539 {
1540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1541 "%s: curr_peer is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -08001542 return -1;
c_hpothu7f63e882013-10-02 19:13:35 +05301543 }
Chilam NG571c65a2013-01-19 12:27:36 +05301544
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001545 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001546 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001547
Chilam Ng01120412013-02-19 18:32:21 -08001548 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001549 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001550 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001551 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001552}
1553
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001554/* Caller has to take the lock before calling this function */
Hoonki Lee27511902013-03-14 18:19:06 -07001555static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1556{
1557 int i;
1558 struct list_head *head;
1559 hddTdlsPeer_t *tmp;
1560 struct list_head *pos, *q;
1561
Hoonki Lee27511902013-03-14 18:19:06 -07001562 for (i = 0; i < 256; i++) {
1563 head = &pHddTdlsCtx->peer_list[i];
1564 list_for_each_safe (pos, q, head) {
1565 tmp = list_entry(pos, hddTdlsPeer_t, node);
1566 tmp->tx_pkt = 0;
1567 tmp->rx_pkt = 0;
1568 }
1569 }
Hoonki Lee27511902013-03-14 18:19:06 -07001570
1571 return ;
1572}
1573
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001574/* Caller has to take the lock before calling this function */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001575static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001576{
1577 int i;
1578 struct list_head *head;
1579 hddTdlsPeer_t *tmp;
1580 struct list_head *pos, *q;
1581
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001582 pHddTdlsCtx->discovery_peer_cnt = 0;
1583
1584 for (i = 0; i < 256; i++) {
1585 head = &pHddTdlsCtx->peer_list[i];
1586 list_for_each_safe (pos, q, head) {
1587 tmp = list_entry(pos, hddTdlsPeer_t, node);
1588 tmp->discovery_processed = 0;
1589 }
1590 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001591
1592 return 0;
1593}
1594
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001595static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001596{
1597 int i;
1598 struct list_head *head;
1599 struct list_head *pos, *q;
1600 int discovery_peer_cnt=0;
1601 hddTdlsPeer_t *tmp;
1602
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001603 /*
1604 * This function expects the callers to acquire the Mutex.
1605 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001606
1607 for (i = 0; i < 256; i++) {
1608 head = &pHddTdlsCtx->peer_list[i];
1609 list_for_each_safe (pos, q, head) {
1610 tmp = list_entry(pos, hddTdlsPeer_t, node);
1611 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001612 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1613 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001614 discovery_peer_cnt++;
1615 }
1616 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001617 return discovery_peer_cnt;
1618}
1619
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001620tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001621{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001622 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1623
c_hpothu7f63e882013-10-02 19:13:35 +05301624 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1625 {
1626 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1627 FL("pHddCtx is not valid"));
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001628 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05301629 }
Lee Hoonkic1262f22013-01-24 21:59:00 -08001630
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001631 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001632}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001633
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001634int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001635{
1636 int i;
1637 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001638 struct list_head *head;
1639 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001640 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001641 tdlsCtx_t *pHddTdlsCtx;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301642 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1643
c_hpothu7f63e882013-10-02 19:13:35 +05301644 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1645 {
1646 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1647 FL("pHddCtx is not valid"));
1648 return 0;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301649 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001650
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001651 init_len = buflen;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001652 len = scnprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n",
1653 "MAC", "Id", "cap", "up", "RSSI");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001654 buf += len;
1655 buflen -= len;
1656 /* 1234567890123456789012345678901234567 */
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001657 len = scnprintf(buf, buflen, "---------------------------------\n");
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001658 buf += len;
1659 buflen -= len;
1660
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301661 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001662 {
1663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301664 FL("unable to lock list"));
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001665 return init_len-buflen;
1666 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001667 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001668 if (NULL == pHddTdlsCtx) {
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301669 mutex_unlock(&pHddCtx->tdls_lock);
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001670 len = scnprintf(buf, buflen, "TDLS not enabled\n");
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001671 return len;
1672 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001673 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001674 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001675
Hoonki Lee387663d2013-02-05 18:08:43 -08001676 list_for_each(pos, head) {
1677 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001678
Hoonki Lee387663d2013-02-05 18:08:43 -08001679 if (buflen < 32+1)
1680 break;
Sameer Thalappilb0a30232013-09-27 15:37:48 -07001681 len = scnprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001682 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1683 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001684 curr_peer->staId,
1685 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07001686 TDLS_IS_CONNECTED(curr_peer) ? "Y":"N",
Hoonki Lee387663d2013-02-05 18:08:43 -08001687 curr_peer->rssi);
1688 buf += len;
1689 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001690 }
1691 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301692 mutex_unlock(&pHddCtx->tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001693 return init_len-buflen;
1694}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001695
1696void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1697{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001698 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301699 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001700
c_hpothu7f63e882013-10-02 19:13:35 +05301701 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1702 {
1703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1704 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
1705 return;
1706 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301707
1708 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001709 {
1710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301711 FL("unable to lock list"));
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07001712 return;
1713 }
1714
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001715 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1716 "%s, update %d discover %d", __func__,
1717 pHddTdlsCtx->threshold_config.tx_period_t,
1718 pHddTdlsCtx->threshold_config.discovery_period_t);
1719
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001720 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1721 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001722 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001723 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001724 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001725
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001726#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001727 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1728 &pHddTdlsCtx->peerDiscoverTimer,
1729 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001730#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001731 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1732 &pHddTdlsCtx->peerUpdateTimer,
1733 pHddTdlsCtx->threshold_config.tx_period_t);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001734 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301735 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001736
1737}
1738
1739void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1740{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001741 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301742 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1743
c_hpothu7f63e882013-10-02 19:13:35 +05301744 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1745 {
1746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1747 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
1748 return;
1749 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001750
1751 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1752
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301753 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001754 {
1755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301756 FL("unable to lock list"));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001757 return;
1758 }
1759 if (NULL == pHddTdlsCtx)
1760 {
c_hpothu7f63e882013-10-02 19:13:35 +05301761 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1762 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301763 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001764 return;
1765 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001766 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001767 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001768
Madan Mohan Koyyalamudi693275b2013-07-22 19:14:09 +05301769 wlan_hdd_tdls_monitor_timers_stop(pHddTdlsCtx);
1770 wlan_hdd_tdls_peer_timers_destroy(pHddTdlsCtx);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001771 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001772
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301773 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001774}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001775
1776void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1777{
1778 pAdapter->mgmtTxCompletionStatus = statusCode;
1779 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1780 __func__, statusCode);
1781 complete(&pAdapter->tdls_mgmt_comp);
1782}
1783
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001784void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001785{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001786 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001787
c_hpothu7f63e882013-10-02 19:13:35 +05301788 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1789 {
1790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1791 FL("pHddCtx is not valid"));
1792 return;
1793 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001794
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301795 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1796 {
1797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301798 FL("unable to lock list"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301799 return;
1800 }
1801
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001802 pHddCtx->connected_peer_count++;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001803 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001804
1805 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1806 __func__, pHddCtx->connected_peer_count);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301807
1808 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001809}
1810
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001811void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001812{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001813 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001814
c_hpothu7f63e882013-10-02 19:13:35 +05301815 if(0 != (wlan_hdd_validate_context(pHddCtx)))
1816 {
1817 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1818 FL("pHddCtx is not valid"));
1819 return;
1820 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001821
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301822 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1823 {
1824 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu7f63e882013-10-02 19:13:35 +05301825 FL("unable to lock list"));
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301826 return;
1827 }
1828
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001829 if (pHddCtx->connected_peer_count)
1830 pHddCtx->connected_peer_count--;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001831 wlan_hdd_tdls_check_power_save_prohibited(pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001832
1833 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1834 __func__, pHddCtx->connected_peer_count);
1835
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301836 mutex_unlock(&pHddCtx->tdls_lock);
1837
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001838}
1839
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001840void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001841{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001842 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001843 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee14621352013-04-16 17:51:19 -07001844 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001845
c_hpothu7f63e882013-10-02 19:13:35 +05301846 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx))
1847 {
1848 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1849 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
1850 return;
1851 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001852
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301853 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Lee14621352013-04-16 17:51:19 -07001854 if (NULL != curr_peer)
1855 {
1856 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1857 "%s: tdls in progress. Dont check for BMPS " MAC_ADDRESS_STR,
1858 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac));
1859 return;
1860 }
1861
Hoonki Lee93e67ff2013-03-19 15:49:25 -07001862 if ((TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic) &&
1863 (0 == pHddCtx->connected_peer_count) &&
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001864 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001865 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001866 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1867 {
1868 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001869 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1870 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001871 hdd_enable_bmps_imps(pHddCtx);
1872 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001873 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001874 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001875 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001876 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1877 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001878 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1879 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001880 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1881 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001882 }
1883 return;
1884}
1885
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001886u8 wlan_hdd_tdls_is_peer_progress(hdd_adapter_t *pAdapter, u8 *mac)
1887{
1888 hddTdlsPeer_t *curr_peer;
1889
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301890 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001891 if (curr_peer == NULL)
c_hpothu7f63e882013-10-02 19:13:35 +05301892 {
1893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1894 "%s: curr_peer is NULL", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001895 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05301896 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001897
1898 return (eTDLS_LINK_CONNECTING == curr_peer->link_status);
1899}
1900
Hoonki Leefb8df672013-04-10 18:20:34 -07001901/* return pointer to hddTdlsPeer_t if TDLS is ongoing. Otherwise return NULL.
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001902 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1903 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1904 mac is NULL, this argument is ignored, and check for all the peer list.
1905 */
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301906static hddTdlsPeer_t *wlan_hdd_tdls_find_progress_peer(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001907{
1908 int i;
1909 struct list_head *head;
1910 hddTdlsPeer_t *curr_peer;
1911 struct list_head *pos;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301912 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);;
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301913
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301914 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05301915 {
1916 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1917 FL("pHddTdlsCtx is NULL"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301918 return NULL;
c_hpothu7f63e882013-10-02 19:13:35 +05301919 }
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05301920
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001921 for (i = 0; i < 256; i++) {
1922 head = &pHddTdlsCtx->peer_list[i];
1923 list_for_each(pos, head) {
1924 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1925 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1926 continue;
1927 }
1928 else
1929 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001930 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001931 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001932 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001933 "%s:" MAC_ADDRESS_STR " eTDLS_LINK_CONNECTING",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001934 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Hoonki Leefb8df672013-04-10 18:20:34 -07001935 return curr_peer;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001936 }
1937 }
1938 }
1939 }
Hoonki Leefb8df672013-04-10 18:20:34 -07001940 return NULL;
1941}
1942
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301943hddTdlsPeer_t *wlan_hdd_tdls_is_progress(hdd_context_t *pHddCtx, u8 *mac, u8 skip_self)
Hoonki Leefb8df672013-04-10 18:20:34 -07001944{
1945 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1946 hdd_adapter_t *pAdapter = NULL;
1947 tdlsCtx_t *pHddTdlsCtx = NULL;
1948 hddTdlsPeer_t *curr_peer= NULL;
1949 VOS_STATUS status = 0;
1950
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301951 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
1952 {
1953 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1954 "%s: unable to lock list", __func__);
1955 return NULL;
1956 }
1957
Hoonki Leefb8df672013-04-10 18:20:34 -07001958 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1959 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1960 {
1961 pAdapter = pAdapterNode->pAdapter;
1962
1963 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1964 if (NULL != pHddTdlsCtx)
1965 {
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301966 curr_peer = wlan_hdd_tdls_find_progress_peer(pAdapter, mac, skip_self);
Hoonki Leefb8df672013-04-10 18:20:34 -07001967 if (curr_peer)
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301968 {
1969 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001970 return curr_peer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301971 }
Hoonki Leefb8df672013-04-10 18:20:34 -07001972 }
1973 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1974 pAdapterNode = pNext;
1975 }
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05301976 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Leefb8df672013-04-10 18:20:34 -07001977 return NULL;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001978}
Hoonki Lee27511902013-03-14 18:19:06 -07001979
1980static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1981{
Hoonki Lee27511902013-03-14 18:19:06 -07001982 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07001983}
1984
1985static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1986{
1987 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001988 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001989 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07001990 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001991
Hoonki Lee27511902013-03-14 18:19:06 -07001992
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001993#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001994 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1995 &pHddTdlsCtx->peerDiscoverTimer,
1996 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001997#endif
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07001998 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
1999 &pHddTdlsCtx->peerUpdateTimer,
2000 pHddTdlsCtx->threshold_config.tx_period_t);
Hoonki Lee27511902013-03-14 18:19:06 -07002001}
2002
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002003void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx,
2004 eTDLSSupportMode tdls_mode,
2005 v_BOOL_t bUpdateLast)
Hoonki Lee27511902013-03-14 18:19:06 -07002006{
2007 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2008 VOS_STATUS status;
2009 hdd_adapter_t *pAdapter;
2010 tdlsCtx_t *pHddTdlsCtx;
2011
2012 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
c_hpothu7f63e882013-10-02 19:13:35 +05302013
2014 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2015 {
2016 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2017 FL("pHddCtx is not valid"));
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302018 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302019 }
Hoonki Lee27511902013-03-14 18:19:06 -07002020
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302021 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
Gopichand Nakkala638ebc72013-03-21 18:04:02 -07002022 {
2023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2024 "%s: unable to lock list", __func__);
2025 return;
2026 }
2027
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002028 if (pHddCtx->tdls_mode == tdls_mode)
2029 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002030 hddLog(TDLS_LOG_LEVEL, "%s already in mode %d", __func__, (int)tdls_mode);
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302031 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002032 return;
2033 }
2034
Hoonki Lee27511902013-03-14 18:19:06 -07002035 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2036
2037 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2038 {
2039 pAdapter = pAdapterNode->pAdapter;
Hoonki Leea6d49be2013-04-05 09:43:25 -07002040 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2041 if (NULL != pHddTdlsCtx)
Hoonki Lee27511902013-03-14 18:19:06 -07002042 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002043 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
2044 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
2045 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
2046 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
2047 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
Hoonki Lee27511902013-03-14 18:19:06 -07002048 }
2049 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2050 pAdapterNode = pNext;
2051 }
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002052 if(bUpdateLast)
2053 {
2054 pHddCtx->tdls_mode_last = tdls_mode;
2055 }
2056 else
2057 {
2058 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
2059 }
Hoonki Lee27511902013-03-14 18:19:06 -07002060 pHddCtx->tdls_mode = tdls_mode;
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002061
Madan Mohan Koyyalamudi263cec12013-10-07 10:57:50 +05302062 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee27511902013-03-14 18:19:06 -07002063}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002064
Hoonki Leed37cbb32013-04-20 00:31:14 -07002065static void wlan_hdd_tdls_pre_setup(struct work_struct *work)
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002066{
Hoonki Leed37cbb32013-04-20 00:31:14 -07002067 tdlsCtx_t *pHddTdlsCtx =
2068 container_of(work, tdlsCtx_t, implicit_setup);
2069 hdd_context_t *pHddCtx;
2070 hddTdlsPeer_t *curr_peer;
Hoonki Leefb8df672013-04-10 18:20:34 -07002071 hddTdlsPeer_t *temp_peer;
Hoonki Leed37cbb32013-04-20 00:31:14 -07002072 int status;
2073
2074 if (NULL == pHddTdlsCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302075 {
2076 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2077 FL("pHddTdlsCtx is NULL"));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002078 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302079 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002080
2081 if (unlikely(TDLS_CTX_MAGIC != pHddTdlsCtx->magic))
c_hpothu7f63e882013-10-02 19:13:35 +05302082 {
2083 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2084 "%s: tdls magic no missmatch %u", __func__, pHddTdlsCtx->magic);
Hoonki Leed37cbb32013-04-20 00:31:14 -07002085 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302086 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002087
2088 pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
Hoonki Leefb8df672013-04-10 18:20:34 -07002089
c_hpothu7f63e882013-10-02 19:13:35 +05302090 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2091 {
2092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2093 FL("pHddCtx is not valid"));
Hoonki Leefb8df672013-04-10 18:20:34 -07002094 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302095 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002096
Hoonki Leed37cbb32013-04-20 00:31:14 -07002097 curr_peer = pHddTdlsCtx->curr_candidate;
2098
2099 if (NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302100 {
2101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2102 FL("curr_peer is NULL"));
2103
Hoonki Leed37cbb32013-04-20 00:31:14 -07002104 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302105 }
Hoonki Leed37cbb32013-04-20 00:31:14 -07002106
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002107 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
2108 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002109 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002110 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
2111 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002112
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302113 temp_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002114 if (NULL != temp_peer)
2115 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002116 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " ongoing. pre_setup ignored",
Hoonki Leefb8df672013-04-10 18:20:34 -07002117 __func__, MAC_ADDR_ARRAY(temp_peer->peerMac));
Hoonki Leed37cbb32013-04-20 00:31:14 -07002118 goto done;
Hoonki Leefb8df672013-04-10 18:20:34 -07002119 }
2120
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002121 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
2122 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
2123
Hoonki Leed37cbb32013-04-20 00:31:14 -07002124 status = wlan_hdd_cfg80211_send_tdls_discover_req(pHddTdlsCtx->pAdapter->wdev.wiphy,
2125 pHddTdlsCtx->pAdapter->dev,
2126 curr_peer->peerMac);
2127
2128 if (0 != status)
2129 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08002130 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: " MAC_ADDRESS_STR " discovery could not sent",
Hoonki Leed37cbb32013-04-20 00:31:14 -07002131 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
2132 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
2133 curr_peer->link_status = eTDLS_LINK_IDLE;
2134 goto done;
2135 }
2136
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002137 pHddTdlsCtx->discovery_sent_cnt++;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302138
2139 if (mutex_lock_interruptible(&pHddCtx->tdls_lock))
2140 {
2141 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2142 "%s: unable to lock list", __func__);
2143 return;
2144 }
2145
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002146 wlan_hdd_tdls_check_power_save_prohibited(pHddTdlsCtx->pAdapter);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302147
2148 mutex_unlock(&pHddCtx->tdls_lock);
Jeff Johnson0299d0a2013-10-30 12:37:43 -07002149 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %u timeout %u msec",
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002150 __func__, pHddTdlsCtx->discovery_sent_cnt,
2151 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002152
2153 wlan_hdd_tdls_timer_restart(pHddTdlsCtx->pAdapter,
2154 &pHddTdlsCtx->peerDiscoveryTimeoutTimer,
2155 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002156
Hoonki Leed37cbb32013-04-20 00:31:14 -07002157done:
2158 pHddTdlsCtx->curr_candidate = NULL;
2159 pHddTdlsCtx->magic = 0;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07002160 return;
2161}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002162
2163tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
2164{
2165 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
2166 hdd_adapter_t *pAdapter = NULL;
2167 tdlsCtx_t *pHddTdlsCtx = NULL;
2168 VOS_STATUS status = 0;
2169 tANI_U32 count = 0;
2170
2171 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
2172 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
2173 {
2174 pAdapter = pAdapterNode->pAdapter;
2175
Hoonki Leea6d49be2013-04-05 09:43:25 -07002176 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2177 if (NULL != pHddTdlsCtx)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002178 {
Hoonki Leea6d49be2013-04-05 09:43:25 -07002179 count = count + pHddTdlsCtx->discovery_sent_cnt;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002180 }
2181 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
2182 pAdapterNode = pNext;
2183 }
2184 return count;
2185}
2186
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07002187void wlan_hdd_tdls_check_power_save_prohibited(hdd_adapter_t *pAdapter)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002188{
2189 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
2190 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2191
2192 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
c_hpothu7f63e882013-10-02 19:13:35 +05302193 {
2194 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2195 FL(" pHddCtx or pHddTdlsCtx points to NULL"));
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002196 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302197 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07002198
2199 if ((0 == pHddCtx->connected_peer_count) &&
2200 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
2201 {
2202 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
2203 return;
2204 }
2205 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
2206 return;
2207}
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002208
2209void wlan_hdd_tdls_free_scan_request (tdls_scan_context_t *tdls_scan_ctx)
2210{
2211 if (NULL == tdls_scan_ctx)
c_hpothu7f63e882013-10-02 19:13:35 +05302212 {
2213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2214 FL("tdls_scan_ctx is NULL"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002215 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302216 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002217
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002218 tdls_scan_ctx->attempt = 0;
Hoonki Leefb8df672013-04-10 18:20:34 -07002219 tdls_scan_ctx->reject = 0;
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002220 tdls_scan_ctx->magic = 0;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002221 tdls_scan_ctx->scan_request = NULL;
2222 return;
2223}
2224
2225int wlan_hdd_tdls_copy_scan_context(hdd_context_t *pHddCtx,
2226 struct wiphy *wiphy,
2227#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2228 struct net_device *dev,
2229#endif
2230 struct cfg80211_scan_request *request)
2231{
2232 tdls_scan_context_t *scan_ctx;
2233
c_hpothu7f63e882013-10-02 19:13:35 +05302234 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2235 {
2236 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2237 FL("pHddCtx is not valid"));
2238 return 0;
2239 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002240
2241 scan_ctx = &pHddCtx->tdls_scan_ctxt;
2242
2243 scan_ctx->wiphy = wiphy;
2244#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2245 scan_ctx->dev = dev;
2246#endif
2247
2248 scan_ctx->scan_request = request;
2249 return 0;
2250}
2251
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002252static void wlan_hdd_tdls_scan_init_work(hdd_context_t *pHddCtx,
2253 struct wiphy *wiphy,
2254#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2255 struct net_device *dev,
2256#endif
2257 struct cfg80211_scan_request *request,
2258 unsigned long delay)
2259{
2260 if (TDLS_CTX_MAGIC != pHddCtx->tdls_scan_ctxt.magic)
2261 {
2262#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2263 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, dev, request);
2264#else
2265 wlan_hdd_tdls_copy_scan_context(pHddCtx, wiphy, request);
2266#endif
2267 pHddCtx->tdls_scan_ctxt.attempt = 0;
2268 pHddCtx->tdls_scan_ctxt.magic = TDLS_CTX_MAGIC;
2269 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002270 schedule_delayed_work(&pHddCtx->tdls_scan_ctxt.tdls_scan_work, delay);
2271}
2272
2273/* return negative = caller should stop and return error code immediately
2274 return 0 = caller should stop and return success immediately
2275 return 1 = caller can continue to scan
2276 */
2277int wlan_hdd_tdls_scan_callback (hdd_adapter_t *pAdapter,
2278 struct wiphy *wiphy,
2279#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2280 struct net_device *dev,
2281#endif
2282 struct cfg80211_scan_request *request)
2283{
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002284 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
2285 u16 connectedTdlsPeers;
Hoonki Leefb8df672013-04-10 18:20:34 -07002286 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002287 unsigned long delay;
2288
c_hpothu7f63e882013-10-02 19:13:35 +05302289 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2290 {
2291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2292 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002293 return 0;
c_hpothu7f63e882013-10-02 19:13:35 +05302294 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002295
2296 /* if tdls is not enabled, then continue scan */
2297 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
2298 return 1;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05302299 curr_peer = wlan_hdd_tdls_is_progress(pHddCtx, NULL, 0);
Hoonki Leefb8df672013-04-10 18:20:34 -07002300 if (NULL != curr_peer)
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002301 {
Hoonki Leefb8df672013-04-10 18:20:34 -07002302 if (pHddCtx->tdls_scan_ctxt.reject++ >= TDLS_MAX_SCAN_REJECT)
2303 {
2304 pHddCtx->tdls_scan_ctxt.reject = 0;
2305 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2306 "%s: " MAC_ADDRESS_STR ". scan rejected %d. force it to idle",
2307 __func__, MAC_ADDR_ARRAY (curr_peer->peerMac), pHddCtx->tdls_scan_ctxt.reject);
2308
2309 wlan_hdd_tdls_set_peer_link_status (curr_peer, eTDLS_LINK_IDLE);
2310 return 1;
2311 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002312 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Leefb8df672013-04-10 18:20:34 -07002313 "%s: tdls in progress. scan rejected %d",
2314 __func__, pHddCtx->tdls_scan_ctxt.reject);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002315 return -EBUSY;
2316 }
2317
2318 /* tdls teardown is ongoing */
2319 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
2320 {
2321 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2322 if (connectedTdlsPeers && (pHddCtx->tdls_scan_ctxt.attempt < TDLS_MAX_SCAN_SCHEDULE))
2323 {
2324 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2325 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2326 "%s: tdls disabled, but still connected_peers %d attempt %d. schedule scan %lu msec",
2327 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt, delay);
2328
2329 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2330#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2331 dev,
2332#endif
2333 request,
2334 msecs_to_jiffies(delay));
2335 /* scan should not continue */
2336 return 0;
2337 }
2338 /* no connected peer or max retry reached, scan continue */
2339 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2340 "%s: tdls disabled. connected_peers %d attempt %d. scan allowed",
2341 __func__, connectedTdlsPeers, pHddCtx->tdls_scan_ctxt.attempt);
2342 return 1;
2343 }
2344 /* while tdls is up, first time scan */
2345 else if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode ||
2346 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode)
2347 {
2348 /* disable implicit trigger logic & tdls operatoin */
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002349 wlan_hdd_tdls_set_mode(pHddCtx, eTDLS_SUPPORT_DISABLED, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002350 /* indicate the teardown all connected to peer */
2351 connectedTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
2352 if (connectedTdlsPeers)
2353 {
2354 tANI_U8 staIdx;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002355 hddTdlsPeer_t *curr_peer;
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002356
2357 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
2358 {
2359 if (pHddCtx->tdlsConnInfo[staIdx].staId)
2360 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002361 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002362 ("%s: indicate TDLS teadown (staId %d)"), __func__, pHddCtx->tdlsConnInfo[staIdx].staId) ;
2363
2364#ifdef CONFIG_TDLS_IMPLICIT
Hoonki Leea6d49be2013-04-05 09:43:25 -07002365 curr_peer = wlan_hdd_tdls_find_all_peer(pHddCtx, pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes);
2366 if(curr_peer)
2367 wlan_hdd_tdls_indicate_teardown(curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002368#endif
2369 }
2370 }
2371 /* schedule scan */
2372 delay = (unsigned long)(TDLS_DELAY_SCAN_PER_CONNECTION*connectedTdlsPeers);
2373
2374 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2375 "%s: tdls enabled (mode %d), connected_peers %d. schedule scan %lu msec",
2376 __func__, pHddCtx->tdls_mode, wlan_hdd_tdlsConnectedPeers(pAdapter),
2377 delay);
2378
2379 wlan_hdd_tdls_scan_init_work (pHddCtx, wiphy,
2380#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
2381 dev,
2382#endif
2383 request,
2384 msecs_to_jiffies(delay));
2385 /* scan should not continue */
2386 return 0;
2387 }
2388 /* no connected peer, scan continue */
2389 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
2390 "%s: tdls_mode %d, and no tdls connection. scan allowed",
2391 __func__, pHddCtx->tdls_mode);
2392 }
2393 return 1;
2394}
2395
2396void wlan_hdd_tdls_scan_done_callback(hdd_adapter_t *pAdapter)
2397{
2398 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002399
c_hpothu7f63e882013-10-02 19:13:35 +05302400 if(0 != (wlan_hdd_validate_context(pHddCtx)))
2401 {
2402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2403 FL("pHddCtx is not valid"));
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002404 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302405 }
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002406
Sunil Dutt41de4e22013-11-14 18:09:02 +05302407
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002408 /* free allocated memory at scan time */
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002409 wlan_hdd_tdls_free_scan_request (&pHddCtx->tdls_scan_ctxt);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002410
2411 /* if tdls was enabled before scan, re-enable tdls mode */
2412 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode_last ||
2413 eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == pHddCtx->tdls_mode_last)
2414 {
Gopichand Nakkala4ddf0192013-03-27 13:41:20 -07002415 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002416 ("%s: revert tdls mode %d"), __func__, pHddCtx->tdls_mode_last);
2417
Gopichand Nakkaladcbcf4e2013-03-23 14:32:39 -07002418 wlan_hdd_tdls_set_mode(pHddCtx, pHddCtx->tdls_mode_last, FALSE);
Hoonki Lee93e67ff2013-03-19 15:49:25 -07002419 }
2420 wlan_hdd_tdls_check_bmps(pAdapter);
2421}
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002422
2423void wlan_hdd_tdls_timer_restart(hdd_adapter_t *pAdapter,
2424 vos_timer_t *timer,
2425 v_U32_t expirationTime)
2426{
2427 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2428
2429 if (NULL == pHddStaCtx)
c_hpothu7f63e882013-10-02 19:13:35 +05302430 {
2431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2432 FL("pHddStaCtx is NULL"));
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002433 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302434 }
Gopichand Nakkala3046fc92013-03-23 13:56:43 -07002435
2436 /* Check whether driver load unload is in progress */
2437 if(vos_is_load_unload_in_progress( VOS_MODULE_ID_VOSS, NULL))
2438 {
2439 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR,
2440 "%s: Driver load/unload is in progress.", __func__);
2441 return;
2442 }
2443
2444 if (hdd_connIsConnected(pHddStaCtx))
2445 {
2446 vos_timer_stop(timer);
2447 vos_timer_start(timer, expirationTime);
2448 }
2449}
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002450void wlan_hdd_tdls_indicate_teardown(hdd_adapter_t *pAdapter,
2451 hddTdlsPeer_t *curr_peer,
2452 tANI_U16 reason)
2453{
2454 if (NULL == pAdapter || NULL == curr_peer)
c_hpothu7f63e882013-10-02 19:13:35 +05302455 {
2456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
2457 FL("parameters passed are invalid"));
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002458 return;
c_hpothu7f63e882013-10-02 19:13:35 +05302459 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07002460
2461 if (eTDLS_LINK_CONNECTED != curr_peer->link_status)
2462 return;
2463
2464 wlan_hdd_tdls_set_peer_link_status(curr_peer, eTDLS_LINK_TEARING);
2465 cfg80211_tdls_oper_request(pAdapter->dev,
2466 curr_peer->peerMac,
2467 NL80211_TDLS_TEARDOWN,
2468 reason,
2469 GFP_KERNEL);
2470}