blob: 2b3f31d581115c37a0de5da3a20396e4cf252b5e [file] [log] [blame]
Kiran V1ccee932012-12-12 14:49:46 -08001/*
Gopichand Nakkala0c1331e2013-01-07 22:49:07 -08002 * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
Kiran V1ccee932012-12-12 14:49:46 -080021
22/**========================================================================
23
24 \file wlan_hdd_tdls.c
25
Chilam NG571c65a2013-01-19 12:27:36 +053026 \brief WLAN Host Device Driver implementation for TDLS
Kiran V1ccee932012-12-12 14:49:46 -080027
Kiran V1ccee932012-12-12 14:49:46 -080028 ========================================================================*/
29
30#include <wlan_hdd_includes.h>
31#include <wlan_hdd_hostapd.h>
32#include <net/cfg80211.h>
33#include <linux/netdevice.h>
34#include <linux/skbuff.h>
Chilam NG571c65a2013-01-19 12:27:36 +053035#include <linux/list.h>
Kiran V1ccee932012-12-12 14:49:46 -080036#include <linux/etherdevice.h>
37#include <net/ieee80211_radiotap.h>
38#include "wlan_hdd_tdls.h"
Chilam NG571c65a2013-01-19 12:27:36 +053039#include "wlan_hdd_cfg80211.h"
Kiran V1ccee932012-12-12 14:49:46 -080040
Chilam NG571c65a2013-01-19 12:27:36 +053041
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080042static struct mutex tdls_lock;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080043static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx);
44static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx);
45static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +053046
Hoonki Lee5a4b2172013-01-29 01:45:53 -080047#ifndef WLAN_FEATURE_TDLS_DEBUG
48#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_INFO
49#else
50#define TDLS_LOG_LEVEL VOS_TRACE_LEVEL_WARN
51#endif
52
Hoonki Lee387663d2013-02-05 18:08:43 -080053static u8 wlan_hdd_tdls_hash_key (u8 *mac)
Hoonki Leef63df0d2013-01-16 19:29:14 -080054{
55 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -080056 u8 key = 0;
57
58 for (i = 0; i < 6; i++)
59 key ^= mac[i];
60
61 return key;
62}
63
Gopichand Nakkala4327a152013-03-04 23:22:42 -080064static v_VOID_t wlan_hdd_tdls_start_peer_discover_timer(tdlsCtx_t *pHddTdlsCtx,
65 tANI_BOOLEAN mutexLock,
66 v_U32_t discoveryExpiry)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080067{
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080068 hdd_station_ctx_t *pHddStaCtx;
69
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080070 if ( mutexLock )
71 {
72 if (mutex_lock_interruptible(&tdls_lock))
73 {
74 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
75 "%s: unable to lock list: %d", __func__, __LINE__);
76 return;
77 }
78 }
79 if (NULL == pHddTdlsCtx)
80 {
81 if ( mutexLock )
82 mutex_unlock(&tdls_lock);
83 return;
84 }
85
Gopichand Nakkala4327a152013-03-04 23:22:42 -080086 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080087 {
88 if ( mutexLock )
89 mutex_unlock(&tdls_lock);
90 return;
91 }
92
Gopichand Nakkala4327a152013-03-04 23:22:42 -080093 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080094 if (hdd_connIsConnected( pHddStaCtx ))
95 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -070096#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080097 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer, discoveryExpiry);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -070098#endif
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -080099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
100 pHddTdlsCtx->ap_rssi);
101 }
102 if ( mutexLock )
103 mutex_unlock(&tdls_lock);
104
105 return;
106}
107
Hoonki Lee387663d2013-02-05 18:08:43 -0800108static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
109{
110 int i;
111 struct list_head *head;
112 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530113 hddTdlsPeer_t *curr_peer;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800114 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800115 tdlsCtx_t *pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800116 int discover_req_sent = 0;
117 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800118 tANI_BOOLEAN doMutexLock = eANI_BOOLEAN_TRUE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800119
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800120 if (mutex_lock_interruptible(&tdls_lock))
121 {
122 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
123 "%s: unable to lock list : %d", __func__, __LINE__);
124 return;
125 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800126
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800127 if (NULL == pHddTdlsCtx)
128 {
129 mutex_unlock(&tdls_lock);
130 return;
131 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800132
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800133 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800134 {
135 mutex_unlock(&tdls_lock);
136 return;
137 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800138
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800139 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pHddTdlsCtx->pAdapter);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800140
Hoonki Lee387663d2013-02-05 18:08:43 -0800141 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
142
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800143 if (0 == pHddTdlsCtx->discovery_peer_cnt)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800144 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt(pHddTdlsCtx);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800145
Chilam NG571c65a2013-01-19 12:27:36 +0530146 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800147 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530148
Hoonki Lee387663d2013-02-05 18:08:43 -0800149 list_for_each (pos, head) {
150 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530151
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800152 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800153 "%d " MAC_ADDRESS_STR " %d %d, %d %d %d %d", i,
154 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800155 curr_peer->discovery_processed,
156 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800157 curr_peer->tdls_support,
158 curr_peer->link_status,
159 curr_peer->discovery_attempt,
160 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800161
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800162 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
163 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530164
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800165 curr_peer->discovery_processed = 1;
166 discover_req_sent++;
167 pHddTdlsCtx->discovery_peer_cnt--;
168
169 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800170 (eTDLS_LINK_IDLE == curr_peer->link_status) &&
Gopichand Nakkalab88f6772013-02-27 18:12:56 -0800171 (curr_peer->tx_pkt >=
172 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800173
174 if (curr_peer->discovery_attempt <
175 pHddTdlsCtx->threshold_config.discovery_tries_n) {
176
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800178 "sme_SendTdlsMgmtFrame(%d)", pHddTdlsCtx->pAdapter->sessionId);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800179
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800180 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
181 pHddTdlsCtx->pAdapter->sessionId,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800182 curr_peer->peerMac,
183 WLAN_TDLS_DISCOVERY_REQUEST,
184 1, 0, NULL, 0, 0);
Gopichand Nakkala273d5a02013-02-19 15:15:09 -0800185 curr_peer->discovery_attempt++;
186 }
187 else
188 {
189 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
190 "%s: Maximum Discovery retries reached", __func__);
191 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
192 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800193
194 }
195 }
Chilam NG571c65a2013-01-19 12:27:36 +0530196 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800197 else
198 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800199 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800200 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800201exit_loop:
Hoonki Leef63df0d2013-01-16 19:29:14 -0800202
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800203 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
204 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
205 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
206 pHddTdlsCtx->discovery_peer_cnt);
207 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800208 doMutexLock = eANI_BOOLEAN_FALSE;
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800209 goto done;
210 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800211 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
212
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800213 mutex_unlock(&tdls_lock);
214
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800215 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530216
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800217 /* Commenting out the following function as it was introducing
218 * a race condition when pHddTdlsCtx is deleted. Also , this
219 * function is consuming more time in the timer callback.
220 * RSSI based trigger needs to revisit this part of the code.
221 */
222
223 /*
224 * wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
225 */
Chilam NG571c65a2013-01-19 12:27:36 +0530226
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800227done:
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800228 wlan_hdd_tdls_start_peer_discover_timer(pHddTdlsCtx, doMutexLock, discover_expiry);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800229
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800230 if ( !doMutexLock )
231 mutex_unlock(&tdls_lock);
232 return;
Hoonki Leef63df0d2013-01-16 19:29:14 -0800233}
Chilam NG571c65a2013-01-19 12:27:36 +0530234
Hoonki Lee387663d2013-02-05 18:08:43 -0800235static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530236{
237 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800238 struct list_head *head;
239 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530240 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800241 tdlsCtx_t *pHddTdlsCtx;
Hoonki Leebfee0342013-01-21 16:43:45 -0800242
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800243 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800244 {
245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
246 "%s: unable to lock list", __func__);
247 return;
248 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800249 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800250 if (NULL == pHddTdlsCtx)
251 {
252 mutex_unlock(&tdls_lock);
253 return;
254 }
255
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800256 if (NULL == pHddTdlsCtx->pAdapter)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800257 {
258 mutex_unlock(&tdls_lock);
259 return;
260 }
261
Chilam NG571c65a2013-01-19 12:27:36 +0530262 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800263 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530264
Hoonki Lee387663d2013-02-05 18:08:43 -0800265 list_for_each (pos, head) {
266 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530267
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800268 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
269 "hdd update cb - %d: " MAC_ADDRESS_STR " -> %d link_status -> %d"
270 "tdls_support -> %d", i,
Chilam Ng01120412013-02-19 18:32:21 -0800271 MAC_ADDR_ARRAY(curr_peer->peerMac),
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800272 curr_peer->tx_pkt, curr_peer->link_status, curr_peer->tdls_support);
Hoonki Lee387663d2013-02-05 18:08:43 -0800273
Chilam NG571c65a2013-01-19 12:27:36 +0530274 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800275 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800276 "%s: (tx %d, rx %d, config %d) " MAC_ADDRESS_STR " (%d) ",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800277 __func__, curr_peer->tx_pkt, curr_peer->rx_pkt,
278 pHddTdlsCtx->threshold_config.tx_packet_n,
Chilam Ng01120412013-02-19 18:32:21 -0800279 MAC_ADDR_ARRAY(curr_peer->peerMac), curr_peer->link_status);
280
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800281 if ((eTDLS_LINK_IDLE == curr_peer->link_status) ||
282 (eTDLS_LINK_DISCOVERING == curr_peer->link_status)){
Chilam NG571c65a2013-01-19 12:27:36 +0530283 if (curr_peer->tx_pkt >=
284 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800285
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800286 if (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800287 {
288
289 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> Tput trigger TDLS SETUP");
Chilam NG571c65a2013-01-19 12:27:36 +0530290#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700291 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam NG571c65a2013-01-19 12:27:36 +0530292#endif
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800293 }
294 else
295 {
296 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800297 "%s: Maximum peer connected already! %d",
298 __func__, wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter) );
Gopichand Nakkalab977a972013-02-18 19:15:09 -0800299 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800300 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530301 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800302#ifdef WLAN_FEATURE_TDLS_DEBUG
303 else {
304 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> ignored.");
305 }
306#endif
Gopichand Nakkala9f7592a2013-02-27 12:41:50 -0800307 if ((((tANI_S32)curr_peer->rssi >
Hoonki Leecdd8e962013-01-20 00:45:46 -0800308 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis +
Gopichand Nakkala9f7592a2013-02-27 12:41:50 -0800309 pHddTdlsCtx->ap_rssi)) ||
310 ((tANI_S32)(curr_peer->rssi >
311 pHddTdlsCtx->threshold_config.rssi_trigger_threshold))) &&
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800312 (HDD_MAX_NUM_TDLS_STA > wlan_hdd_tdlsConnectedPeers(pHddTdlsCtx->pAdapter))){
Chilam NG571c65a2013-01-19 12:27:36 +0530313
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800314 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
315 "%s: RSSI (peer %d > ap %d + hysteresis %d) triggering to %02x:%02x:%02x:%02x:%02x:%02x ",
316 __func__, (tANI_S32)curr_peer->rssi,
317 pHddTdlsCtx->ap_rssi,
318 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis),
319 curr_peer->peerMac[0], curr_peer->peerMac[1], curr_peer->peerMac[2],
320 curr_peer->peerMac[3], curr_peer->peerMac[4], curr_peer->peerMac[5]);
Chilam NG571c65a2013-01-19 12:27:36 +0530321
322#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800323 cfg80211_tdls_oper_request(pHddTdlsCtx->pAdapter->dev,
Chilam NG571c65a2013-01-19 12:27:36 +0530324 curr_peer->peerMac,
325 NL80211_TDLS_SETUP, FALSE,
326 GFP_KERNEL);
327#endif
328 }
329 } else {
Chilam Ng01120412013-02-19 18:32:21 -0800330 if ((tANI_S32)curr_peer->rssi <
331 (tANI_S32)pHddTdlsCtx->threshold_config.rssi_teardown_threshold) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800332
Chilam Ng01120412013-02-19 18:32:21 -0800333 VOS_TRACE( VOS_MODULE_ID_HDD,
334 VOS_TRACE_LEVEL_WARN,
335 "Tear down - low RSSI: " MAC_ADDRESS_STR "!",
336 MAC_ADDR_ARRAY(curr_peer->peerMac));
337#ifdef CONFIG_TDLS_IMPLICIT
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800338 cfg80211_tdls_oper_request(pHddTdlsCtx->pAdapter->dev,
Chilam Ng01120412013-02-19 18:32:21 -0800339 curr_peer->peerMac,
340 NL80211_TDLS_TEARDOWN, FALSE,
341 GFP_KERNEL);
342#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800343 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530344 }
Chilam Ng01120412013-02-19 18:32:21 -0800345
346 if ((curr_peer->tx_pkt <
347 pHddTdlsCtx->threshold_config.idle_packet_n) &&
348 (curr_peer->rx_pkt <
349 pHddTdlsCtx->threshold_config.idle_packet_n)) {
350 if (VOS_TIMER_STATE_RUNNING !=
351 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
353 "Tx/Rx Idle timer start: " MAC_ADDRESS_STR "!",
354 MAC_ADDR_ARRAY(curr_peer->peerMac));
355 vos_timer_start( &curr_peer->peerIdleTimer,
356 pHddTdlsCtx->threshold_config.idle_timeout_t );
357 }
358 } else {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800359 if (VOS_TIMER_STATE_RUNNING ==
360 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Chilam Ng01120412013-02-19 18:32:21 -0800361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
362 "Tx/Rx Idle timer stop: " MAC_ADDRESS_STR "!",
363 MAC_ADDR_ARRAY(curr_peer->peerMac));
364 vos_timer_stop( &curr_peer->peerIdleTimer);
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800365 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800366 }
Chilam Ng01120412013-02-19 18:32:21 -0800367
Hoonki Leecdd8e962013-01-20 00:45:46 -0800368// if (curr_peer->rssi <
369// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
370// pHddTdlsCtx->ap_rssi)) {
371//
372//#ifdef CONFIG_TDLS_IMPLICIT
373// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
374// curr_peer->peerMac,
375// NL80211_TDLS_TEARDOWN, FALSE,
376// GFP_KERNEL);
377//#endif
378// }
Chilam NG571c65a2013-01-19 12:27:36 +0530379 }
Chilam Ng01120412013-02-19 18:32:21 -0800380 } else if (eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) {
381 if (eTDLS_LINK_CONNECTED != curr_peer->link_status) {
382 if (curr_peer->tx_pkt >=
383 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam Ng01120412013-02-19 18:32:21 -0800384
385 if (++curr_peer->discovery_attempt <
386 pHddTdlsCtx->threshold_config.discovery_tries_n) {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700387 wlan_hdd_tdls_pre_setup(pHddTdlsCtx, curr_peer);
Chilam Ng01120412013-02-19 18:32:21 -0800388 }
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800389 else
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800390 {
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800391 curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800392 curr_peer->link_status = eTDLS_LINK_IDLE;
393 }
Chilam Ng01120412013-02-19 18:32:21 -0800394
395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
396 "Tput triggering TDLS discovery: " MAC_ADDRESS_STR "!",
397 MAC_ADDR_ARRAY(curr_peer->peerMac));
398 }
399 }
Chilam NG571c65a2013-01-19 12:27:36 +0530400 }
401
Hoonki Leecdd8e962013-01-20 00:45:46 -0800402next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530403 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800404 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800405 }
Chilam NG571c65a2013-01-19 12:27:36 +0530406 }
407
408 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
409 pHddTdlsCtx->threshold_config.tx_period_t );
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800410 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530411}
412
Chilam Ng1279e232013-01-25 15:06:52 -0800413static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
414{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800415#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800416 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
417
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800418 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800419 "%s: Tx/Rx Idle " MAC_ADDRESS_STR " trigger teardown",
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800420 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800421 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800422 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800423 {
424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
425 "%s: unable to lock list", __func__);
426 return;
427 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800428
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800429 cfg80211_tdls_oper_request(curr_peer->pHddTdlsCtx->pAdapter->dev,
Chilam Ng1279e232013-01-25 15:06:52 -0800430 curr_peer->peerMac,
Hoonki Leea34dd892013-02-05 22:56:02 -0800431 NL80211_TDLS_TEARDOWN,
432 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
Chilam Ng1279e232013-01-25 15:06:52 -0800433 GFP_KERNEL);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800434 mutex_unlock(&tdls_lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800435#endif
436}
437
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700438static v_VOID_t wlan_hdd_tdls_discovery_timeout_peer_cb(v_PVOID_t userData)
439{
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700440 int i;
441 struct list_head *head;
442 hddTdlsPeer_t *tmp;
443 struct list_head *pos, *q;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700444 tdlsCtx_t *pHddTdlsCtx;
445
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700446 if (mutex_lock_interruptible(&tdls_lock))
447 {
448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
449 "%s: unable to lock list", __func__);
450 return ;
451 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700452 pHddTdlsCtx = (tdlsCtx_t *)userData;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700453
454 if ( NULL == pHddTdlsCtx )
455 {
456 mutex_unlock(&tdls_lock);
457 return ;
458 }
459
460 for (i = 0; i < 256; i++) {
461 head = &pHddTdlsCtx->peer_list[i];
462 list_for_each_safe (pos, q, head) {
463 tmp = list_entry(pos, hddTdlsPeer_t, node);
464 if (eTDLS_LINK_DISCOVERING == tmp->link_status)
465 {
466 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
467 "%s: " MAC_ADDRESS_STR " to idle state", __func__,
468 MAC_ADDR_ARRAY(tmp->peerMac));
469 tmp->link_status = eTDLS_LINK_IDLE;
470 }
471 }
472 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700473
474 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700475 wlan_hdd_tdls_set_power_save_prohibited(pHddTdlsCtx->pAdapter);
476
477 mutex_unlock(&tdls_lock);
478
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700479 wlan_hdd_tdls_check_bmps(pHddTdlsCtx->pAdapter);
480
481 return;
482}
483
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800484static void wlan_hdd_tdls_free_list(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800485{
486 int i;
487 struct list_head *head;
488 hddTdlsPeer_t *tmp;
489 struct list_head *pos, *q;
490
491 if (NULL == pHddTdlsCtx) return;
492
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800493
494 for (i = 0; i < 256; i++) {
495 head = &pHddTdlsCtx->peer_list[i];
496 list_for_each_safe (pos, q, head) {
497 tmp = list_entry(pos, hddTdlsPeer_t, node);
498 list_del(pos);
499 vos_mem_free(tmp);
500 }
501 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800502}
503
Hoonki Lee27511902013-03-14 18:19:06 -0700504int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter)
Chilam Ng01120412013-02-19 18:32:21 -0800505{
Chilam Ng01120412013-02-19 18:32:21 -0800506 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Lee27511902013-03-14 18:19:06 -0700507 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng01120412013-02-19 18:32:21 -0800508 int i;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800509 v_U8_t staIdx;
Chilam Ng01120412013-02-19 18:32:21 -0800510
Hoonki Lee27511902013-03-14 18:19:06 -0700511 mutex_init(&tdls_lock);
Chilam Ng01120412013-02-19 18:32:21 -0800512
Hoonki Lee27511902013-03-14 18:19:06 -0700513 if ((FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport) ||
514 (FALSE == sme_IsFeatureSupportedByFW(TDLS)))
515 {
516 pHddCtx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED;
517 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled (%d) or FW doesn't support (%d)!",
519 __func__, pHddCtx->cfg_ini->fEnableTDLSSupport,
520 sme_IsFeatureSupportedByFW(TDLS));
521 return 0;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800522 }
523
Hoonki Lee27511902013-03-14 18:19:06 -0700524 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
525
526 if (NULL == pHddTdlsCtx) {
527 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
528 pAdapter->sessionCtx.station.pHddTdlsCtx = NULL;
529 return -1;
530 }
531
532 pAdapter->sessionCtx.station.pHddTdlsCtx = pHddTdlsCtx;
533
534 /* initialize TDLS global context */
535 pHddCtx->connected_peer_count = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700536 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pAdapter), 0);
Hoonki Lee27511902013-03-14 18:19:06 -0700537
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800538 for (staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
539 {
540 pHddCtx->tdlsConnInfo[staIdx].staId = 0;
541 pHddCtx->tdlsConnInfo[staIdx].sessionId = 255;
542 vos_mem_zero(&pHddCtx->tdlsConnInfo[staIdx].peerMac,
543 sizeof(v_MACADDR_t)) ;
Chilam Ng01120412013-02-19 18:32:21 -0800544 }
545
Hoonki Lee27511902013-03-14 18:19:06 -0700546 /* initialize TDLS pAdater context */
547 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
548
549 pHddTdlsCtx->pAdapter = pAdapter;
550
551 for (i = 0; i < 256; i++)
552 {
553 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
554 }
555
Chilam Ng01120412013-02-19 18:32:21 -0800556 vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
557 VOS_TIMER_TYPE_SW,
558 wlan_hdd_tdls_discover_peer_cb,
559 pHddTdlsCtx);
560
561 vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
562 VOS_TIMER_TYPE_SW,
563 wlan_hdd_tdls_update_peer_cb,
564 pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700565 vos_timer_init(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
566 VOS_TIMER_TYPE_SW,
567 wlan_hdd_tdls_discovery_timeout_peer_cb,
568 pHddTdlsCtx);
Chilam Ng01120412013-02-19 18:32:21 -0800569
Hoonki Lee27511902013-03-14 18:19:06 -0700570 /* remember configuration even if it is not used right now. it could be used later */
571 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
572 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
573 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
574 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
575 pHddTdlsCtx->threshold_config.idle_timeout_t = pHddCtx->cfg_ini->fTDLSIdleTimeout;
576 pHddTdlsCtx->threshold_config.idle_packet_n = pHddCtx->cfg_ini->fTDLSIdlePacketThreshold;
577 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRSSIHysteresis;
578 pHddTdlsCtx->threshold_config.rssi_trigger_threshold = pHddCtx->cfg_ini->fTDLSRSSITriggerThreshold;
579 pHddTdlsCtx->threshold_config.rssi_teardown_threshold = pHddCtx->cfg_ini->fTDLSRSSITeardownThreshold;
Chilam NG571c65a2013-01-19 12:27:36 +0530580
Chilam Ng01120412013-02-19 18:32:21 -0800581 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
Hoonki Lee387663d2013-02-05 18:08:43 -0800582 {
Chilam Ng01120412013-02-19 18:32:21 -0800583 pHddCtx->tdls_mode = eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY;
Hoonki Leebf870f32013-01-19 15:53:30 +0530584 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Leebf870f32013-01-19 15:53:30 +0530585 }
Hoonki Lee27511902013-03-14 18:19:06 -0700586 else
587 {
588 pHddCtx->tdls_mode = eTDLS_SUPPORT_ENABLED;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700589#ifdef FEATURE_WLAN_TDLS_INTERNAL
Hoonki Lee27511902013-03-14 18:19:06 -0700590 vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
591 pHddTdlsCtx->threshold_config.discovery_period_t );
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700592#endif
Chilam NG571c65a2013-01-19 12:27:36 +0530593
Hoonki Lee27511902013-03-14 18:19:06 -0700594 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
595 pHddTdlsCtx->threshold_config.tx_period_t );
596 }
597
598 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530599}
600
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800601void wlan_hdd_tdls_exit(hdd_adapter_t *pAdapter)
Chilam NG571c65a2013-01-19 12:27:36 +0530602{
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800603 tdlsCtx_t *pHddTdlsCtx;
604
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800605 if (mutex_lock_interruptible(&tdls_lock))
606 {
607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
608 "%s: unable to lock list", __func__);
609 return;
610 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800611
612 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800613 if (NULL == pHddTdlsCtx)
614 {
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800615 mutex_unlock(&tdls_lock);
Hoonki Leebfee0342013-01-21 16:43:45 -0800616 hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
617 return;
618 }
619
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800620 /* must stop timer here before freeing peer list, because peerIdleTimer is
621 part of peer list structure. */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800622 wlan_hdd_tdls_timers_destroy(pHddTdlsCtx);
623 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Chilam Nga75d8b62013-01-29 01:35:59 -0800624
625 vos_mem_free(pHddTdlsCtx);
626 pHddTdlsCtx = NULL;
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800627 mutex_unlock(&tdls_lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530628}
629
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800630/* stop all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800631static void wlan_hdd_tdls_timers_stop(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800632{
633 int i;
634 struct list_head *head;
635 struct list_head *pos;
636 hddTdlsPeer_t *curr_peer;
637
638 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
639 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700640 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800641
642 for (i = 0; i < 256; i++)
643 {
644 head = &pHddTdlsCtx->peer_list[i];
645
646 list_for_each (pos, head) {
647 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
648
649 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800650 "%s: " MAC_ADDRESS_STR " -> stop idle timer",
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800651 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800652 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800653 vos_timer_stop ( &curr_peer->peerIdleTimer );
654 }
655 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800656}
657
658/* destroy all the tdls timers running */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800659static void wlan_hdd_tdls_timers_destroy(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800660{
661 int i;
662 struct list_head *head;
663 struct list_head *pos;
664 hddTdlsPeer_t *curr_peer;
665
666 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
667 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
668 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
669 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700670 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
671 vos_timer_destroy(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800672
673 for (i = 0; i < 256; i++)
674 {
675 head = &pHddTdlsCtx->peer_list[i];
676
677 list_for_each (pos, head) {
678 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
679
680 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -0800681 "%s: " MAC_ADDRESS_STR " -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800682 __func__,
Chilam Ng01120412013-02-19 18:32:21 -0800683 MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800684 vos_timer_stop ( &curr_peer->peerIdleTimer );
685 vos_timer_destroy ( &curr_peer->peerIdleTimer );
686 }
687 }
688}
689
Hoonki Lee387663d2013-02-05 18:08:43 -0800690/* if mac address exist, return pointer
691 if mac address doesn't exist, create a list and add, return pointer
692 return NULL if fails to get new mac address
693*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800694hddTdlsPeer_t *wlan_hdd_tdls_get_peer(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530695{
Hoonki Lee387663d2013-02-05 18:08:43 -0800696 struct list_head *head;
697 hddTdlsPeer_t *peer;
698 u8 key;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800699 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530700
Hoonki Lee387663d2013-02-05 18:08:43 -0800701 if (NULL == pHddTdlsCtx)
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800702 {
703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
704 "%s: pHddTdlsCtx is NULL", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800705 return NULL;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800706 }
Hoonki Leebfee0342013-01-21 16:43:45 -0800707
Hoonki Lee387663d2013-02-05 18:08:43 -0800708 /* if already there, just update */
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800709 peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800710 if (peer != NULL)
711 {
712 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530713 }
714
Hoonki Lee387663d2013-02-05 18:08:43 -0800715 /* not found, allocate and add the list */
716 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
717 if (NULL == peer) {
718 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
719 return NULL;
720 }
Chilam NG571c65a2013-01-19 12:27:36 +0530721
Hoonki Lee387663d2013-02-05 18:08:43 -0800722 key = wlan_hdd_tdls_hash_key(mac);
723 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530724
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800725 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -0800726 {
727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
728 "%s: unable to lock list", __func__);
729 return NULL;
730 }
Chilam NG571c65a2013-01-19 12:27:36 +0530731
Hoonki Lee387663d2013-02-05 18:08:43 -0800732 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
733 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800734 peer->pHddTdlsCtx = pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -0800735
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800736 vos_timer_init(&peer->peerIdleTimer,
737 VOS_TIMER_TYPE_SW,
738 wlan_hdd_tdls_idle_cb,
739 peer);
740
Hoonki Lee387663d2013-02-05 18:08:43 -0800741 list_add_tail(&peer->node, head);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -0800742 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -0800743
744 return peer;
745}
746
Hoonki Lee27511902013-03-14 18:19:06 -0700747void wlan_hdd_tdls_set_cap(hdd_adapter_t *pAdapter,
748 u8* mac,
749 tTDLSCapType cap)
750{
751 hddTdlsPeer_t *curr_peer;
752
753 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
754 if (curr_peer == NULL)
755 return;
756
757 curr_peer->tdls_support = cap;
758
759 return;
760}
761
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800762void wlan_hdd_tdls_set_peer_link_status(hddTdlsPeer_t *curr_peer, tTDLSLinkStatus status)
Hoonki Lee387663d2013-02-05 18:08:43 -0800763{
764 if (curr_peer == NULL)
765 return;
766
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800767 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer " MAC_ADDRESS_STR " link status to %u",
Chilam Ng01120412013-02-19 18:32:21 -0800768 MAC_ADDR_ARRAY(curr_peer->peerMac), status);
Chilam NG571c65a2013-01-19 12:27:36 +0530769
770 curr_peer->link_status = status;
771
Chilam NG571c65a2013-01-19 12:27:36 +0530772}
773
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800774void wlan_hdd_tdls_set_link_status(hdd_adapter_t *pAdapter,
775 u8* mac,
776 tTDLSLinkStatus linkStatus)
777{
778 hddTdlsPeer_t *curr_peer;
779
780 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
781 if (curr_peer == NULL)
782 return;
783
784 curr_peer->link_status= linkStatus;
785
786 return;
787}
788
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800789int wlan_hdd_tdls_recv_discovery_resp(hdd_adapter_t *pAdapter, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530790{
791 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700792 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530793
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800794 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700795
796 if (NULL == curr_peer)
Hoonki Lee387663d2013-02-05 18:08:43 -0800797 return -1;
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700798
799 if (pHddTdlsCtx->discovery_sent_cnt)
800 pHddTdlsCtx->discovery_sent_cnt--;
801
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700802 wlan_hdd_tdls_set_power_save_prohibited(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700803 if (0 == pHddTdlsCtx->discovery_sent_cnt)
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700804 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700805 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700806 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700807
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800808 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700809 "Discovery(%lu) Response from " MAC_ADDRESS_STR " link_status %d",
810 pHddTdlsCtx->discovery_sent_cnt, MAC_ADDR_ARRAY(curr_peer->peerMac),
811 curr_peer->link_status);
812
Gopichand Nakkala8b00c632013-03-08 19:47:52 -0800813 if (eTDLS_LINK_DISCOVERING == curr_peer->link_status)
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800814 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -0700815 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
816 "Indicating Set-Up to supplicant");
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800817 cfg80211_tdls_oper_request(pAdapter->dev,
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800818 curr_peer->peerMac,
819 NL80211_TDLS_SETUP, FALSE,
820 GFP_KERNEL);
Gopichand Nakkala05922802013-03-14 12:23:19 -0700821 curr_peer->link_status = eTDLS_LINK_DISCOVERED;
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800822 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -0700823 else
824 {
825 wlan_hdd_tdls_check_bmps(pAdapter);
826 }
Chilam NG571c65a2013-01-19 12:27:36 +0530827
Gopichand Nakkala901e8922013-03-04 23:45:58 -0800828 curr_peer->tdls_support = eTDLS_CAP_SUPPORTED;
Hoonki Lee387663d2013-02-05 18:08:43 -0800829 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530830}
831
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800832int wlan_hdd_tdls_set_rssi(hdd_adapter_t *pAdapter, u8 *mac, tANI_S8 rxRssi)
Chilam NG571c65a2013-01-19 12:27:36 +0530833{
834 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530835
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800836 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800837 if (curr_peer == NULL)
838 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530839
840 curr_peer->rssi = rxRssi;
841
Hoonki Lee387663d2013-02-05 18:08:43 -0800842 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530843}
844
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800845int wlan_hdd_tdls_set_responder(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 responder)
Hoonki Leea34dd892013-02-05 22:56:02 -0800846{
847 hddTdlsPeer_t *curr_peer;
848
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800849 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800850 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800851 return -1;
852
853 curr_peer->is_responder = responder;
854
855 return 0;
856}
857
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800858int wlan_hdd_tdls_get_responder(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Leea34dd892013-02-05 22:56:02 -0800859{
860 hddTdlsPeer_t *curr_peer;
861
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800862 curr_peer = wlan_hdd_tdls_find_peer(pAdapter, mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800863 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800864 return -1;
865
866 return (curr_peer->is_responder);
867}
868
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800869int wlan_hdd_tdls_set_signature(hdd_adapter_t *pAdapter, u8 *mac, tANI_U8 uSignature)
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800870{
871 hddTdlsPeer_t *curr_peer;
872
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800873 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee11f7dda2013-02-14 16:55:44 -0800874 if (curr_peer == NULL)
875 return -1;
876
877 curr_peer->signature = uSignature;
878
879 return 0;
880}
881
Hoonki Leea34dd892013-02-05 22:56:02 -0800882
Hoonki Lee387663d2013-02-05 18:08:43 -0800883void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530884{
Chilam NG571c65a2013-01-19 12:27:36 +0530885 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +0530886}
887
Hoonki Lee387663d2013-02-05 18:08:43 -0800888void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -0800889{
Chilam Ng1279e232013-01-25 15:06:52 -0800890 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -0800891}
892
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800893int wlan_hdd_tdls_increment_pkt_count(hdd_adapter_t *pAdapter, u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +0530894{
Hoonki Lee387663d2013-02-05 18:08:43 -0800895 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800896 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Chilam NG571c65a2013-01-19 12:27:36 +0530897
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800898 if (eTDLS_SUPPORT_ENABLED != pHddCtx->tdls_mode)
899 return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -0800900
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800901 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -0800902 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +0530903 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530904
Chilam Ng1279e232013-01-25 15:06:52 -0800905 if (tx)
906 curr_peer->tx_pkt++;
907 else
908 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +0530909
Chilam NG571c65a2013-01-19 12:27:36 +0530910 return 0;
911}
912
Hoonki Lee27511902013-03-14 18:19:06 -0700913static int wlan_hdd_tdls_check_config(tdls_config_params_t *config)
914{
915 if (config->tdls > 2)
916 {
917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 1st argument %d. <0...2>", __func__, config->tdls);
918 return -1;
919 }
920 if (config->tx_period_t < CFG_TDLS_TX_STATS_PERIOD_MIN ||
921 config->tx_period_t > CFG_TDLS_TX_STATS_PERIOD_MAX)
922 {
923 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 2nd argument %d. <%d...%d>", __func__, config->tx_period_t,
924 CFG_TDLS_TX_STATS_PERIOD_MIN, CFG_TDLS_TX_STATS_PERIOD_MAX);
925 return -1;
926 }
927 if (config->tx_packet_n < CFG_TDLS_TX_PACKET_THRESHOLD_MIN ||
928 config->tx_packet_n > CFG_TDLS_TX_PACKET_THRESHOLD_MAX)
929 {
930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 3rd argument %d. <%d...%d>", __func__, config->tx_packet_n,
931 CFG_TDLS_TX_PACKET_THRESHOLD_MIN, CFG_TDLS_TX_PACKET_THRESHOLD_MAX);
932 return -1;
933 }
934 if (config->discovery_period_t < CFG_TDLS_DISCOVERY_PERIOD_MIN ||
935 config->discovery_period_t > CFG_TDLS_DISCOVERY_PERIOD_MAX)
936 {
937 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 4th argument %d. <%d...%d>", __func__, config->discovery_period_t,
938 CFG_TDLS_DISCOVERY_PERIOD_MIN, CFG_TDLS_DISCOVERY_PERIOD_MAX);
939 return -1;
940 }
941 if (config->discovery_tries_n < CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN ||
942 config->discovery_tries_n > CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX)
943 {
944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 5th argument %d. <%d...%d>", __func__, config->discovery_tries_n,
945 CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MIN, CFG_TDLS_MAX_DISCOVERY_ATTEMPT_MAX);
946 return -1;
947 }
948 if (config->idle_timeout_t < CFG_TDLS_IDLE_TIMEOUT_MIN ||
949 config->idle_timeout_t > CFG_TDLS_IDLE_TIMEOUT_MAX)
950 {
951 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 6th argument %d. <%d...%d>", __func__, config->idle_timeout_t,
952 CFG_TDLS_IDLE_TIMEOUT_MIN, CFG_TDLS_IDLE_TIMEOUT_MAX);
953 return -1;
954 }
955 if (config->idle_packet_n < CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN ||
956 config->idle_packet_n > CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX)
957 {
958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 7th argument %d. <%d...%d>", __func__, config->idle_packet_n,
959 CFG_TDLS_IDLE_PACKET_THRESHOLD_MIN, CFG_TDLS_IDLE_PACKET_THRESHOLD_MAX);
960 return -1;
961 }
962 if (config->rssi_hysteresis < CFG_TDLS_RSSI_HYSTERESIS_MIN ||
963 config->rssi_hysteresis > CFG_TDLS_RSSI_HYSTERESIS_MAX)
964 {
965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 8th argument %d. <%d...%d>", __func__, config->rssi_hysteresis,
966 CFG_TDLS_RSSI_HYSTERESIS_MIN, CFG_TDLS_RSSI_HYSTERESIS_MAX);
967 return -1;
968 }
969 if (config->rssi_trigger_threshold < CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN ||
970 config->rssi_trigger_threshold > CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX)
971 {
972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 9th argument %d. <%d...%d>", __func__, config->rssi_trigger_threshold,
973 CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MIN, CFG_TDLS_RSSI_TRIGGER_THRESHOLD_MAX);
974 return -1;
975 }
976 if (config->rssi_teardown_threshold < CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN ||
977 config->rssi_teardown_threshold > CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX)
978 {
979 hddLog(VOS_TRACE_LEVEL_ERROR, "%s invalid 10th argument %d. <%d...%d>", __func__, config->rssi_teardown_threshold,
980 CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MIN, CFG_TDLS_RSSI_TEARDOWN_THRESHOLD_MAX);
981 return -1;
982 }
983 return 0;
984}
985
Chilam Ng01120412013-02-19 18:32:21 -0800986int wlan_hdd_tdls_set_params(struct net_device *dev, tdls_config_params_t *config)
Chilam NG571c65a2013-01-19 12:27:36 +0530987{
Chilam Ng01120412013-02-19 18:32:21 -0800988 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
989 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -0800990 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Hoonki Lee27511902013-03-14 18:19:06 -0700991 eTDLSSupportMode req_tdls_mode;
Hoonki Leebfee0342013-01-21 16:43:45 -0800992
Hoonki Lee27511902013-03-14 18:19:06 -0700993 if (NULL == pHddTdlsCtx)
994 {
995 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
996 return -1;
Chilam Ng01120412013-02-19 18:32:21 -0800997 }
Chilam NG571c65a2013-01-19 12:27:36 +0530998
Hoonki Lee27511902013-03-14 18:19:06 -0700999 if (wlan_hdd_tdls_check_config(config) != 0)
1000 {
1001 return -1;
1002 }
1003
1004 /* config->tdls is mapped to 0->1, 1->2, 2->3 */
1005 req_tdls_mode = config->tdls + 1;
1006 if (pHddCtx->tdls_mode == req_tdls_mode)
1007 {
1008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s already in mode %d", __func__, config->tdls);
1009 return -1;
1010 }
1011
1012 /* copy the configuration only when given tdls mode is implicit trigger enable */
1013 if (eTDLS_SUPPORT_ENABLED == req_tdls_mode)
1014 {
Chilam Ng01120412013-02-19 18:32:21 -08001015 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
1016 }
Chilam NG571c65a2013-01-19 12:27:36 +05301017
Chilam Ng01120412013-02-19 18:32:21 -08001018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1019 "iw set tdls params: %d %d %d %d %d %d %d %d %d %d",
1020 config->tdls,
1021 config->tx_period_t,
1022 config->tx_packet_n,
1023 config->discovery_period_t,
1024 config->discovery_tries_n,
1025 config->idle_timeout_t,
1026 config->idle_packet_n,
1027 config->rssi_hysteresis,
1028 config->rssi_trigger_threshold,
1029 config->rssi_teardown_threshold);
Chilam NG571c65a2013-01-19 12:27:36 +05301030
Hoonki Lee27511902013-03-14 18:19:06 -07001031 wlan_hdd_tdls_set_mode(pHddCtx, req_tdls_mode);
Chilam Ng01120412013-02-19 18:32:21 -08001032
Chilam NG571c65a2013-01-19 12:27:36 +05301033 return 0;
1034}
1035
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001036int wlan_hdd_tdls_set_sta_id(hdd_adapter_t *pAdapter, u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -08001037{
Hoonki Lee387663d2013-02-05 18:08:43 -08001038 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001039
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001040 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001041 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +05301042 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301043
Hoonki Lee387663d2013-02-05 18:08:43 -08001044 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +05301045
1046 return 0;
Kiran V1ccee932012-12-12 14:49:46 -08001047}
1048
Hoonki Lee387663d2013-02-05 18:08:43 -08001049/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
1050 otherwise, it returns NULL
1051*/
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001052hddTdlsPeer_t *wlan_hdd_tdls_find_peer(hdd_adapter_t *pAdapter, u8 *mac)
Kiran V1ccee932012-12-12 14:49:46 -08001053{
Hoonki Lee387663d2013-02-05 18:08:43 -08001054 u8 key;
1055 struct list_head *pos;
1056 struct list_head *head;
1057 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001058 tdlsCtx_t *pHddTdlsCtx;
Hoonki Lee387663d2013-02-05 18:08:43 -08001059
Hoonki Lee387663d2013-02-05 18:08:43 -08001060
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001061 if (mutex_lock_interruptible(&tdls_lock))
Hoonki Lee387663d2013-02-05 18:08:43 -08001062 {
1063 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1064 "%s: unable to lock list", __func__);
1065 return NULL;
1066 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001067 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001068 if (NULL == pHddTdlsCtx)
1069 {
1070 mutex_unlock(&tdls_lock);
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1072 "%s: pHddTdlsCtx is NULL", __func__);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001073 return NULL;
1074 }
1075
1076 key = wlan_hdd_tdls_hash_key(mac);
1077
1078 head = &pHddTdlsCtx->peer_list[key];
Hoonki Lee387663d2013-02-05 18:08:43 -08001079
1080 list_for_each(pos, head) {
1081 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1082 if (!memcmp(mac, curr_peer->peerMac, 6)) {
1083 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1084 "findTdlsPeer: found staId %d", curr_peer->staId);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001085 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001086 return curr_peer;
1087 }
1088 }
1089
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001090 mutex_unlock(&tdls_lock);
Hoonki Lee387663d2013-02-05 18:08:43 -08001091 return NULL;
1092}
1093
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001094int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, u8 *mac)
Hoonki Lee387663d2013-02-05 18:08:43 -08001095{
Chilam Ng01120412013-02-19 18:32:21 -08001096 hdd_context_t *pHddCtx;
Chilam NG571c65a2013-01-19 12:27:36 +05301097 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -08001098
Chilam Ng01120412013-02-19 18:32:21 -08001099 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
1100
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001101 curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee387663d2013-02-05 18:08:43 -08001102 if (curr_peer == NULL)
1103 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +05301104
Gopichand Nakkala901e8922013-03-04 23:45:58 -08001105 curr_peer->link_status = eTDLS_LINK_IDLE;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001106 curr_peer->staId = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -08001107
Chilam Ng01120412013-02-19 18:32:21 -08001108 if(eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode) {
Chilam Nga75d8b62013-01-29 01:35:59 -08001109 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -08001110 }
Hoonki Lee387663d2013-02-05 18:08:43 -08001111 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -08001112}
1113
Hoonki Lee27511902013-03-14 18:19:06 -07001114static void wlan_tdd_tdls_reset_tx_rx(tdlsCtx_t *pHddTdlsCtx)
1115{
1116 int i;
1117 struct list_head *head;
1118 hddTdlsPeer_t *tmp;
1119 struct list_head *pos, *q;
1120
1121 if (mutex_lock_interruptible(&tdls_lock))
1122 {
1123 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1124 "%s: unable to lock list", __func__);
1125 return ;
1126 }
1127 if ( NULL == pHddTdlsCtx )
1128 {
1129 mutex_unlock(&tdls_lock);
1130 return ;
1131 }
1132
1133 for (i = 0; i < 256; i++) {
1134 head = &pHddTdlsCtx->peer_list[i];
1135 list_for_each_safe (pos, q, head) {
1136 tmp = list_entry(pos, hddTdlsPeer_t, node);
1137 tmp->tx_pkt = 0;
1138 tmp->rx_pkt = 0;
1139 }
1140 }
1141 mutex_unlock(&tdls_lock);
1142
1143 return ;
1144}
1145
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001146static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001147{
1148 int i;
1149 struct list_head *head;
1150 hddTdlsPeer_t *tmp;
1151 struct list_head *pos, *q;
1152
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001153 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001154 {
1155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1156 "%s: unable to lock list", __func__);
1157 return -1;
1158 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001159 if ( NULL == pHddTdlsCtx )
1160 {
1161 mutex_unlock(&tdls_lock);
1162 return -1;
1163 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001164
1165 pHddTdlsCtx->discovery_peer_cnt = 0;
1166
1167 for (i = 0; i < 256; i++) {
1168 head = &pHddTdlsCtx->peer_list[i];
1169 list_for_each_safe (pos, q, head) {
1170 tmp = list_entry(pos, hddTdlsPeer_t, node);
1171 tmp->discovery_processed = 0;
1172 }
1173 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001174 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001175
1176 return 0;
1177}
1178
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001179static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(tdlsCtx_t *pHddTdlsCtx)
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001180{
1181 int i;
1182 struct list_head *head;
1183 struct list_head *pos, *q;
1184 int discovery_peer_cnt=0;
1185 hddTdlsPeer_t *tmp;
1186
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001187 /*
1188 * This function expects the callers to acquire the Mutex.
1189 */
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001190
1191 for (i = 0; i < 256; i++) {
1192 head = &pHddTdlsCtx->peer_list[i];
1193 list_for_each_safe (pos, q, head) {
1194 tmp = list_entry(pos, hddTdlsPeer_t, node);
1195 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Chilam Ng01120412013-02-19 18:32:21 -08001196 "%s, %d, " MAC_ADDRESS_STR, __func__, i,
1197 MAC_ADDR_ARRAY(tmp->peerMac));
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001198 discovery_peer_cnt++;
1199 }
1200 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001201 return discovery_peer_cnt;
1202}
1203
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001204tANI_U16 wlan_hdd_tdlsConnectedPeers(hdd_adapter_t *pAdapter)
Lee Hoonkic1262f22013-01-24 21:59:00 -08001205{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001206 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1207
1208 if (NULL == pHddCtx)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001209 return 0;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001210
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001211 return pHddCtx->connected_peer_count;
Lee Hoonkic1262f22013-01-24 21:59:00 -08001212}
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001213
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001214int wlan_hdd_tdls_get_all_peers(hdd_adapter_t *pAdapter, char *buf, int buflen)
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001215{
1216 int i;
1217 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -08001218 struct list_head *head;
1219 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001220 hddTdlsPeer_t *curr_peer;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001221 tdlsCtx_t *pHddTdlsCtx;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001222
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001223
1224 init_len = buflen;
1225 len = snprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", "MAC", "Id", "cap", "up", "RSSI");
1226 buf += len;
1227 buflen -= len;
1228 /* 1234567890123456789012345678901234567 */
1229 len = snprintf(buf, buflen, "---------------------------------\n");
1230 buf += len;
1231 buflen -= len;
1232
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001233 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkala91b09262013-02-10 14:27:02 -08001234 {
1235 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1236 "%s: unable to lock list", __func__);
1237 return init_len-buflen;
1238 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001239 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001240 if (NULL == pHddTdlsCtx) {
1241 mutex_unlock(&tdls_lock);
1242 len = snprintf(buf, buflen, "TDLS not enabled\n");
1243 return len;
1244 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001245 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -08001246 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001247
Hoonki Lee387663d2013-02-05 18:08:43 -08001248 list_for_each(pos, head) {
1249 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001250
Hoonki Lee387663d2013-02-05 18:08:43 -08001251 if (buflen < 32+1)
1252 break;
1253 len = snprintf(buf, buflen,
Chilam Ng01120412013-02-19 18:32:21 -08001254 MAC_ADDRESS_STR"%3d%4s%3s%5d\n",
1255 MAC_ADDR_ARRAY(curr_peer->peerMac),
Hoonki Lee387663d2013-02-05 18:08:43 -08001256 curr_peer->staId,
1257 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
1258 (curr_peer->link_status == eTDLS_LINK_CONNECTED) ? "Y":"N",
1259 curr_peer->rssi);
1260 buf += len;
1261 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001262 }
1263 }
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001264 mutex_unlock(&tdls_lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -08001265 return init_len-buflen;
1266}
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001267
1268void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
1269{
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001270 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001271 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001272
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001273 if (NULL == pHddTdlsCtx) return;
1274
1275 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1276 "%s, update %d discover %d", __func__,
1277 pHddTdlsCtx->threshold_config.tx_period_t,
1278 pHddTdlsCtx->threshold_config.discovery_period_t);
1279
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001280 if (eTDLS_SUPPORT_ENABLED == pHddCtx->tdls_mode)
1281 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001282 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001283 pHddTdlsCtx->discovery_sent_cnt = 0;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001284 wlan_hdd_tdls_set_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001285
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001286#ifdef FEATURE_WLAN_TDLS_INTERNAL
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001287 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer,
1288 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001289#endif
Gopichand Nakkala9d76a9b2013-02-28 15:38:37 -08001290 vos_timer_start(&pHddTdlsCtx->peerUpdateTimer,
1291 pHddTdlsCtx->threshold_config.tx_period_t);
1292 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001293
1294}
1295
1296void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
1297{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001298 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001299
1300 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
1301
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001302 if (mutex_lock_interruptible(&tdls_lock))
1303 {
1304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1305 "%s: unable to lock list", __func__);
1306 return;
1307 }
1308 if (NULL == pHddTdlsCtx)
1309 {
1310 mutex_unlock(&tdls_lock);
1311 return;
1312 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001313 pHddTdlsCtx->discovery_sent_cnt = 0;
1314 wlan_hdd_tdls_set_power_save_prohibited(pHddTdlsCtx->pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001315
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001316 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
1317 wlan_hdd_tdls_free_list(pHddTdlsCtx);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001318
1319 mutex_unlock(&tdls_lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -08001320}
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001321
1322void wlan_hdd_tdls_mgmt_completion_callback(hdd_adapter_t *pAdapter, tANI_U32 statusCode)
1323{
1324 pAdapter->mgmtTxCompletionStatus = statusCode;
1325 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Mgmt TX Completion %d",
1326 __func__, statusCode);
1327 complete(&pAdapter->tdls_mgmt_comp);
1328}
1329
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001330void wlan_hdd_tdls_increment_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001331{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001332 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001333
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001334 if (NULL == pHddCtx) return;
1335
1336 pHddCtx->connected_peer_count++;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001337 wlan_hdd_tdls_set_power_save_prohibited(pAdapter);
1338
1339 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1340 __func__, pHddCtx->connected_peer_count);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001341}
1342
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001343void wlan_hdd_tdls_decrement_peer_count(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001344{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001345 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001346
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001347 if (NULL == pHddCtx) return;
1348
1349 if (pHddCtx->connected_peer_count)
1350 pHddCtx->connected_peer_count--;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001351 wlan_hdd_tdls_set_power_save_prohibited(pAdapter);
1352
1353 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: %d",
1354 __func__, pHddCtx->connected_peer_count);
1355
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001356}
1357
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001358void wlan_hdd_tdls_check_bmps(hdd_adapter_t *pAdapter)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001359{
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001360 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001361 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001362
Gopichand Nakkala16c02842013-03-18 12:31:35 -07001363 if ((NULL == pHddCtx) || (NULL == pHddTdlsCtx)) return;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001364
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001365 if ((0 == pHddCtx->connected_peer_count) &&
1366 (0 == pHddTdlsCtx->discovery_sent_cnt))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001367 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001368 if (FALSE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1369 {
1370 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001371 "%s: No TDLS peer connected/discovery sent. Enable BMPS",
1372 __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001373 hdd_enable_bmps_imps(pHddCtx);
1374 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001375 }
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001376 else
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001377 {
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001378 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
1379 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001380 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1381 "%s: TDLS peer connected. Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001382 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1383 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001384 }
1385 return;
1386}
1387
1388/* return TRUE if TDLS is ongoing
1389 * mac - if NULL check for all the peer list, otherwise, skip this mac when skip_self is TRUE
1390 * skip_self - if TRUE, skip this mac. otherwise, check all the peer list. if
1391 mac is NULL, this argument is ignored, and check for all the peer list.
1392 */
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001393u8 wlan_hdd_tdls_is_progress(hdd_adapter_t *pAdapter, u8 *mac, u8 skip_self)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001394{
1395 int i;
1396 struct list_head *head;
1397 hddTdlsPeer_t *curr_peer;
1398 struct list_head *pos;
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001399 tdlsCtx_t *pHddTdlsCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001400
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001401 if (mutex_lock_interruptible(&tdls_lock))
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001402 {
1403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1404 "%s: unable to lock list", __func__);
1405 return FALSE;
1406 }
Gopichand Nakkala4327a152013-03-04 23:22:42 -08001407 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001408 if (NULL == pHddTdlsCtx)
1409 {
1410 mutex_unlock(&tdls_lock);
1411 return FALSE;
1412 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001413
1414 for (i = 0; i < 256; i++) {
1415 head = &pHddTdlsCtx->peer_list[i];
1416 list_for_each(pos, head) {
1417 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
1418 if (skip_self && mac && !memcmp(mac, curr_peer->peerMac, 6)) {
1419 continue;
1420 }
1421 else
1422 {
Gopichand Nakkala8b00c632013-03-08 19:47:52 -08001423 if (eTDLS_LINK_CONNECTING == curr_peer->link_status)
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001424 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07001425 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
1426 "%s:" MAC_ADDRESS_STR "is in eTDLS_LINK_CONNECTING",
1427 __func__, MAC_ADDR_ARRAY(curr_peer->peerMac));
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001428 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001429 return TRUE;
1430 }
1431 }
1432 }
1433 }
1434
Gopichand Nakkalaeb69b602013-02-27 11:40:31 -08001435 mutex_unlock(&tdls_lock);
Gopichand Nakkalab977a972013-02-18 19:15:09 -08001436 return FALSE;
1437}
Hoonki Lee27511902013-03-14 18:19:06 -07001438
1439static void wlan_hdd_tdls_implicit_disable(tdlsCtx_t *pHddTdlsCtx)
1440{
1441 if (mutex_lock_interruptible(&tdls_lock))
1442 {
1443 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
1444 "%s: unable to lock list", __func__);
1445 return;
1446 }
1447
1448 wlan_hdd_tdls_timers_stop(pHddTdlsCtx);
1449
1450 mutex_unlock(&tdls_lock);
1451}
1452
1453static void wlan_hdd_tdls_implicit_enable(tdlsCtx_t *pHddTdlsCtx)
1454{
1455 wlan_hdd_tdls_peer_reset_discovery_processed(pHddTdlsCtx);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001456 pHddTdlsCtx->discovery_sent_cnt = 0;
Hoonki Lee27511902013-03-14 18:19:06 -07001457 wlan_tdd_tdls_reset_tx_rx(pHddTdlsCtx);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001458 wlan_hdd_tdls_set_power_save_prohibited(pHddTdlsCtx->pAdapter);
1459
Hoonki Lee27511902013-03-14 18:19:06 -07001460
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001461#ifdef FEATURE_WLAN_TDLS_INTERNAL
Hoonki Lee27511902013-03-14 18:19:06 -07001462 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer,
1463 pHddTdlsCtx->threshold_config.discovery_period_t);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001464#endif
Hoonki Lee27511902013-03-14 18:19:06 -07001465
1466 vos_timer_start(&pHddTdlsCtx->peerUpdateTimer,
1467 pHddTdlsCtx->threshold_config.tx_period_t);
1468}
1469
1470void wlan_hdd_tdls_set_mode(hdd_context_t *pHddCtx, eTDLSSupportMode tdls_mode)
1471{
1472 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1473 VOS_STATUS status;
1474 hdd_adapter_t *pAdapter;
1475 tdlsCtx_t *pHddTdlsCtx;
1476
1477 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s mode %d", __func__, (int)tdls_mode);
1478
1479 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1480
1481 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1482 {
1483 pAdapter = pAdapterNode->pAdapter;
1484 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1485 if (NULL != pHddTdlsCtx)
1486 {
1487 if(eTDLS_SUPPORT_ENABLED == tdls_mode)
1488 wlan_hdd_tdls_implicit_enable(pHddTdlsCtx);
1489 else if((eTDLS_SUPPORT_DISABLED == tdls_mode) ||
1490 (eTDLS_SUPPORT_EXPLICIT_TRIGGER_ONLY == tdls_mode))
1491 wlan_hdd_tdls_implicit_disable(pHddTdlsCtx);
1492 }
1493 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1494 pAdapterNode = pNext;
1495 }
1496 pHddCtx->tdls_mode_last = pHddCtx->tdls_mode;
1497 pHddCtx->tdls_mode = tdls_mode;
1498}
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001499
1500void wlan_hdd_tdls_pre_setup(tdlsCtx_t *pHddTdlsCtx,
1501 hddTdlsPeer_t *curr_peer)
1502{
1503 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter);
1504
1505 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter)))
1506 {
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001507 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s: Disable BMPS", __func__);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001508 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
1509 }
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001510
1511 if (eTDLS_CAP_UNKNOWN != curr_peer->tdls_support)
1512 curr_peer->link_status = eTDLS_LINK_DISCOVERING;
1513
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001514 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter),
1515 pHddTdlsCtx->pAdapter->sessionId,
1516 curr_peer->peerMac,
1517 WLAN_TDLS_DISCOVERY_REQUEST,
1518 1, 0, NULL, 0, 0);
1519 pHddTdlsCtx->discovery_sent_cnt++;
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001520 wlan_hdd_tdls_set_power_save_prohibited(pHddTdlsCtx->pAdapter);
1521 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "%s: discovery count %lu timeout %lu msec",
1522 __func__, pHddTdlsCtx->discovery_sent_cnt,
1523 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001524 vos_timer_stop(&pHddTdlsCtx->peerDiscoveryTimeoutTimer);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001525 vos_timer_start(&pHddTdlsCtx->peerDiscoveryTimeoutTimer,
1526 pHddTdlsCtx->threshold_config.tx_period_t - TDLS_DISCOVERY_TIMEOUT_BEFORE_UPDATE);
Gopichand Nakkala75e7b282013-03-15 18:37:13 -07001527
1528 return;
1529}
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -07001530
1531tANI_U32 wlan_hdd_tdls_discovery_sent_cnt(hdd_context_t *pHddCtx)
1532{
1533 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
1534 hdd_adapter_t *pAdapter = NULL;
1535 tdlsCtx_t *pHddTdlsCtx = NULL;
1536 VOS_STATUS status = 0;
1537 tANI_U32 count = 0;
1538
1539 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
1540 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
1541 {
1542 pAdapter = pAdapterNode->pAdapter;
1543
1544 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1545 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
1546 {
1547 pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1548 if (NULL != pHddTdlsCtx)
1549 {
1550 count = count + pHddTdlsCtx->discovery_sent_cnt;
1551 }
1552 }
1553 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
1554 pAdapterNode = pNext;
1555 }
1556 return count;
1557}
1558
1559void wlan_hdd_tdls_set_power_save_prohibited(hdd_adapter_t *pAdapter)
1560{
1561 tdlsCtx_t *pHddTdlsCtx = WLAN_HDD_GET_TDLS_CTX_PTR(pAdapter);
1562 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1563
1564 if ((NULL == pHddTdlsCtx) || (NULL == pHddCtx))
1565 return;
1566
1567 if ((0 == pHddCtx->connected_peer_count) &&
1568 (0 == wlan_hdd_tdls_discovery_sent_cnt(pHddCtx)))
1569 {
1570 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 0);
1571 return;
1572 }
1573 sme_SetTdlsPowerSaveProhibited(WLAN_HDD_GET_HAL_CTX(pHddTdlsCtx->pAdapter), 1);
1574 return;
1575}