blob: 2ac7e0dedafb976e028c24fe3bad05295436ed6e [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
Chilam Nga75d8b62013-01-29 01:35:59 -080042static tdlsCtx_t *pHddTdlsCtx;
43static v_BOOL_t tdlsImplicitTrigger;
Gopichand Nakkalac3694582013-02-13 20:51:22 -080044static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(void);
45static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(void);
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
64static v_VOID_t wlan_hdd_tdls_discover_peer_cb( v_PVOID_t userData )
65{
66 int i;
67 struct list_head *head;
68 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +053069 hddTdlsPeer_t *curr_peer;
Hoonki Leebfee0342013-01-21 16:43:45 -080070 hdd_adapter_t *pAdapter;
71 hdd_context_t *pHddCtx;
Gopichand Nakkalac3694582013-02-13 20:51:22 -080072 hdd_station_ctx_t *pHddStaCtx;
73 int discover_req_sent = 0;
74 v_U32_t discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
75
Hoonki Leebfee0342013-01-21 16:43:45 -080076
77 if (NULL == pHddTdlsCtx) return;
78
79 pAdapter = WLAN_HDD_GET_PRIV_PTR(pHddTdlsCtx->dev);
Gopichand Nakkalac3694582013-02-13 20:51:22 -080080
81 if (NULL == pAdapter) return;
82
83 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Hoonki Leebfee0342013-01-21 16:43:45 -080084 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Leef63df0d2013-01-16 19:29:14 -080085
Hoonki Lee387663d2013-02-05 18:08:43 -080086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "%s: ", __func__);
87
Gopichand Nakkalac3694582013-02-13 20:51:22 -080088 if (0 == pHddTdlsCtx->discovery_peer_cnt)
89 pHddTdlsCtx->discovery_peer_cnt = wlan_hdd_get_tdls_discovery_peer_cnt();
90
91 if (-1 == pHddTdlsCtx->discovery_peer_cnt) {
92 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
93
94 goto done;
95 }
96
Gopichand Nakkala91b09262013-02-10 14:27:02 -080097 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
98 {
99 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800100 "%s: unable to lock list : %d", __func__, __LINE__);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800101 return;
102 }
103
Chilam NG571c65a2013-01-19 12:27:36 +0530104 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800105 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530106
Hoonki Lee387663d2013-02-05 18:08:43 -0800107 list_for_each (pos, head) {
108 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530109
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800110 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800111 "%d %02x:%02x:%02x:%02x:%02x:%02x %d %d, %d %d %d %d", i,
Hoonki Lee387663d2013-02-05 18:08:43 -0800112 curr_peer->peerMac[0],
113 curr_peer->peerMac[1],
114 curr_peer->peerMac[2],
115 curr_peer->peerMac[3],
116 curr_peer->peerMac[4],
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800117 curr_peer->peerMac[5],
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800118 curr_peer->discovery_processed,
119 discover_req_sent,
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800120 curr_peer->tdls_support,
121 curr_peer->link_status,
122 curr_peer->discovery_attempt,
123 pHddTdlsCtx->threshold_config.discovery_tries_n);
Hoonki Lee387663d2013-02-05 18:08:43 -0800124
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800125 if (discover_req_sent < TDLS_MAX_DISCOVER_REQS_PER_TIMER) {
126 if (!curr_peer->discovery_processed) {
Chilam NG571c65a2013-01-19 12:27:36 +0530127
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800128 curr_peer->discovery_processed = 1;
129 discover_req_sent++;
130 pHddTdlsCtx->discovery_peer_cnt--;
131
132 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
133 (eTDLS_LINK_NOT_CONNECTED == curr_peer->link_status) &&
134 (curr_peer->discovery_attempt <
135 pHddTdlsCtx->threshold_config.discovery_tries_n)) {
136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
137 "sme_SendTdlsMgmtFrame(%d)", pAdapter->sessionId);
138
139 sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
140 pAdapter->sessionId,
141 curr_peer->peerMac,
142 WLAN_TDLS_DISCOVERY_REQUEST,
143 1, 0, NULL, 0, 0);
144
145 }
146 }
Chilam NG571c65a2013-01-19 12:27:36 +0530147 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800148 else
149 goto exit_loop;
Hoonki Lee387663d2013-02-05 18:08:43 -0800150 }
Hoonki Leef63df0d2013-01-16 19:29:14 -0800151 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800152exit_loop:
153 mutex_unlock(&pHddTdlsCtx->lock);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800154
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800155 if (0 != pHddTdlsCtx->discovery_peer_cnt) {
156 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
157 "discovery_peer_cnt is %d , Starting SUB_DISCOVERY_TIMER",
158 pHddTdlsCtx->discovery_peer_cnt);
159 discover_expiry = TDLS_SUB_DISCOVERY_PERIOD;
160 goto done;
161 }
162
163 discover_expiry = pHddTdlsCtx->threshold_config.discovery_period_t;
164
165 wlan_hdd_tdls_peer_reset_discovery_processed();
Chilam NG571c65a2013-01-19 12:27:36 +0530166
167 wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
168
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800169done:
170 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
171 {
172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
173 "%s: unable to lock list: %d", __func__, __LINE__);
174 return;
175 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800176
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800177 if (hdd_connIsConnected( pHddStaCtx ))
178 {
179 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer, discover_expiry);
180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
181 pHddTdlsCtx->ap_rssi);
182 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800183 mutex_unlock(&pHddTdlsCtx->lock);
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800184
Hoonki Leef63df0d2013-01-16 19:29:14 -0800185}
Chilam NG571c65a2013-01-19 12:27:36 +0530186
Hoonki Lee387663d2013-02-05 18:08:43 -0800187static v_VOID_t wlan_hdd_tdls_update_peer_cb( v_PVOID_t userData )
Chilam NG571c65a2013-01-19 12:27:36 +0530188{
189 int i;
Hoonki Lee387663d2013-02-05 18:08:43 -0800190 struct list_head *head;
191 struct list_head *pos;
Chilam NG571c65a2013-01-19 12:27:36 +0530192 hddTdlsPeer_t *curr_peer;
193
Hoonki Leebfee0342013-01-21 16:43:45 -0800194 if (NULL == pHddTdlsCtx) return;
195
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800196 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
197 {
198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
199 "%s: unable to lock list", __func__);
200 return;
201 }
202
Chilam NG571c65a2013-01-19 12:27:36 +0530203 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800204 head = &pHddTdlsCtx->peer_list[i];
Chilam NG571c65a2013-01-19 12:27:36 +0530205
Hoonki Lee387663d2013-02-05 18:08:43 -0800206 list_for_each (pos, head) {
207 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
Chilam NG571c65a2013-01-19 12:27:36 +0530208
Hoonki Lee387663d2013-02-05 18:08:43 -0800209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
210 "hdd update cb - %d: %x %x %x %x %x %x -> %d\n", i,
211 curr_peer->peerMac[0],
212 curr_peer->peerMac[1],
213 curr_peer->peerMac[2],
214 curr_peer->peerMac[3],
215 curr_peer->peerMac[4],
216 curr_peer->peerMac[5],
217 curr_peer->tx_pkt);
218
Chilam NG571c65a2013-01-19 12:27:36 +0530219 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800220 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
221 "%s: (tx %d, rx %d, config %d) %02x:%02x:%02x:%02x:%02x:%02x (%d) ",
222 __func__, curr_peer->tx_pkt, curr_peer->rx_pkt,
223 pHddTdlsCtx->threshold_config.tx_packet_n,
224 curr_peer->peerMac[0], curr_peer->peerMac[1], curr_peer->peerMac[2],
225 curr_peer->peerMac[3], curr_peer->peerMac[4], curr_peer->peerMac[5],
226 curr_peer->link_status);
Chilam NG571c65a2013-01-19 12:27:36 +0530227 if (eTDLS_LINK_CONNECTED != curr_peer->link_status) {
228 if (curr_peer->tx_pkt >=
229 pHddTdlsCtx->threshold_config.tx_packet_n) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800230
231 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> Tput trigger TDLS SETUP");
Chilam NG571c65a2013-01-19 12:27:36 +0530232#ifdef CONFIG_TDLS_IMPLICIT
233 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
234 curr_peer->peerMac,
235 NL80211_TDLS_SETUP, FALSE,
236 GFP_KERNEL);
237#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800238 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530239 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800240#ifdef WLAN_FEATURE_TDLS_DEBUG
241 else {
242 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> ignored.");
243 }
244#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800245 if ((tANI_S32)curr_peer->rssi >
246 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis +
Chilam NG571c65a2013-01-19 12:27:36 +0530247 pHddTdlsCtx->ap_rssi)) {
248
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800249 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
250 "%s: RSSI (peer %d > ap %d + hysteresis %d) triggering to %02x:%02x:%02x:%02x:%02x:%02x ",
251 __func__, (tANI_S32)curr_peer->rssi,
252 pHddTdlsCtx->ap_rssi,
253 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis),
254 curr_peer->peerMac[0], curr_peer->peerMac[1], curr_peer->peerMac[2],
255 curr_peer->peerMac[3], curr_peer->peerMac[4], curr_peer->peerMac[5]);
Chilam NG571c65a2013-01-19 12:27:36 +0530256
257#ifdef CONFIG_TDLS_IMPLICIT
258 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
259 curr_peer->peerMac,
260 NL80211_TDLS_SETUP, FALSE,
261 GFP_KERNEL);
262#endif
263 }
264 } else {
Chilam Ng47d06d62013-02-04 20:25:05 -0800265 /* if we are receiving pakcets (rx_pkt > 0), don't start
266 * the idle timer regardless of tx
267 */
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800268 if ((curr_peer->rx_pkt == 0) &&
Chilam Ng47d06d62013-02-04 20:25:05 -0800269 (curr_peer->tx_pkt <
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800270 pHddTdlsCtx->threshold_config.tx_packet_n)) {
Chilam Ng1279e232013-01-25 15:06:52 -0800271 if (VOS_TIMER_STATE_RUNNING !=
272 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800273 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> start Idle Timer (%d)", pHddTdlsCtx->threshold_config.rx_timeout_t);
Chilam Ng1279e232013-01-25 15:06:52 -0800274 vos_timer_start( &curr_peer->peerIdleTimer,
275 pHddTdlsCtx->threshold_config.rx_timeout_t );
276 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800277
Hoonki Leecdd8e962013-01-20 00:45:46 -0800278 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530279 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800280 else {
281 if (VOS_TIMER_STATE_RUNNING ==
282 vos_timer_getCurrentState(&curr_peer->peerIdleTimer)) {
283 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> stop Idle Timer ");
284 vos_timer_stop ( &curr_peer->peerIdleTimer );
285 }
286#ifdef WLAN_FEATURE_TDLS_DEBUG
287 else
288 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL, "-> idle time was not running. ignored.");
289#endif
290 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800291// if (curr_peer->rssi <
292// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
293// pHddTdlsCtx->ap_rssi)) {
294//
295//#ifdef CONFIG_TDLS_IMPLICIT
296// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
297// curr_peer->peerMac,
298// NL80211_TDLS_TEARDOWN, FALSE,
299// GFP_KERNEL);
300//#endif
301// }
Chilam NG571c65a2013-01-19 12:27:36 +0530302 }
303 }
304
Hoonki Leecdd8e962013-01-20 00:45:46 -0800305next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530306 curr_peer->tx_pkt = 0;
Chilam Ng1279e232013-01-25 15:06:52 -0800307 curr_peer->rx_pkt = 0;
Hoonki Lee387663d2013-02-05 18:08:43 -0800308 }
Chilam NG571c65a2013-01-19 12:27:36 +0530309 }
310
311 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
312 pHddTdlsCtx->threshold_config.tx_period_t );
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800313 mutex_unlock(&pHddTdlsCtx->lock);
Chilam NG571c65a2013-01-19 12:27:36 +0530314}
315
Chilam Ng1279e232013-01-25 15:06:52 -0800316static v_VOID_t wlan_hdd_tdls_idle_cb( v_PVOID_t userData )
317{
Lee Hoonkic1262f22013-01-24 21:59:00 -0800318#ifdef CONFIG_TDLS_IMPLICIT
Chilam Ng1279e232013-01-25 15:06:52 -0800319 hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
320
Chilam Ng1279e232013-01-25 15:06:52 -0800321
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800322 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
323 "%s: Tx/Rx Idle %02x:%02x:%02x:%02x:%02x:%02x trigger teardown",
324 __func__,
325 curr_peer->peerMac[0], curr_peer->peerMac[1], curr_peer->peerMac[2],
326 curr_peer->peerMac[3], curr_peer->peerMac[4], curr_peer->peerMac[5]);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800327 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
328 {
329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
330 "%s: unable to lock list", __func__);
331 return;
332 }
Hoonki Lee5a4b2172013-01-29 01:45:53 -0800333
Chilam Ng1279e232013-01-25 15:06:52 -0800334 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
335 curr_peer->peerMac,
Hoonki Leea34dd892013-02-05 22:56:02 -0800336 NL80211_TDLS_TEARDOWN,
337 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON,
Chilam Ng1279e232013-01-25 15:06:52 -0800338 GFP_KERNEL);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800339 mutex_unlock(&pHddTdlsCtx->lock);
Chilam Ng1279e232013-01-25 15:06:52 -0800340#endif
341}
342
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800343static void wlan_hdd_tdls_free_list(void)
344{
345 int i;
346 struct list_head *head;
347 hddTdlsPeer_t *tmp;
348 struct list_head *pos, *q;
349
350 if (NULL == pHddTdlsCtx) return;
351
352 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
353 {
354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
355 "%s: unable to lock list", __func__);
356 return;
357 }
358
359 for (i = 0; i < 256; i++) {
360 head = &pHddTdlsCtx->peer_list[i];
361 list_for_each_safe (pos, q, head) {
362 tmp = list_entry(pos, hddTdlsPeer_t, node);
363 list_del(pos);
364 vos_mem_free(tmp);
365 }
366 }
367 mutex_unlock(&pHddTdlsCtx->lock);
368
369}
370
Chilam NG571c65a2013-01-19 12:27:36 +0530371int wlan_hdd_tdls_init(struct net_device *dev)
372{
Hoonki Lee387663d2013-02-05 18:08:43 -0800373 int i;
Chilam NG571c65a2013-01-19 12:27:36 +0530374 VOS_STATUS status;
Hoonki Leebf870f32013-01-19 15:53:30 +0530375 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
376 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Chilam NG571c65a2013-01-19 12:27:36 +0530377
Hoonki Lee387663d2013-02-05 18:08:43 -0800378 if (FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport)
Hoonki Leebf870f32013-01-19 15:53:30 +0530379 {
380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800381 return 0;
Hoonki Leebf870f32013-01-19 15:53:30 +0530382 }
383
384 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Chilam NG571c65a2013-01-19 12:27:36 +0530385 if (NULL == pHddTdlsCtx) {
386 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
387 return -1;
388 }
389
390 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
391
392 pHddTdlsCtx->dev = dev;
393
Hoonki Lee387663d2013-02-05 18:08:43 -0800394 mutex_init(&pHddTdlsCtx->lock);
395 for (i = 0; i < 256; i++)
396 {
397 INIT_LIST_HEAD(&pHddTdlsCtx->peer_list[i]);
398 }
399
Chilam Nga75d8b62013-01-29 01:35:59 -0800400 tdlsImplicitTrigger = pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger;
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800401
402 status = vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
403 VOS_TIMER_TYPE_SW,
404 wlan_hdd_tdls_discover_peer_cb,
405 pHddTdlsCtx);
406
407 status = vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
408 VOS_TIMER_TYPE_SW,
409 wlan_hdd_tdls_update_peer_cb,
410 pHddTdlsCtx);
411
Hoonki Lee387663d2013-02-05 18:08:43 -0800412 if (FALSE == tdlsImplicitTrigger)
Hoonki Leebf870f32013-01-19 15:53:30 +0530413 {
414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
Hoonki Lee387663d2013-02-05 18:08:43 -0800415 return 0;
Hoonki Leebf870f32013-01-19 15:53:30 +0530416 }
417 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
418 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
419 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
420 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
421 pHddTdlsCtx->threshold_config.rx_timeout_t = pHddCtx->cfg_ini->fTDLSRxIdleTimeout;
422 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRssiHysteresis;
Chilam NG571c65a2013-01-19 12:27:36 +0530423
Chilam NG571c65a2013-01-19 12:27:36 +0530424 return 0;
425}
426
427void wlan_hdd_tdls_exit()
428{
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800429 if (NULL == pHddTdlsCtx)
430 {
Hoonki Leebfee0342013-01-21 16:43:45 -0800431 hddLog(VOS_TRACE_LEVEL_WARN, "%s TDLS not enabled, exiting!", __func__);
432 return;
433 }
434
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800435 /* must stop timer here before freeing peer list, because peerIdleTimer is
436 part of peer list structure. */
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800437 wlan_hdd_tdls_timers_destroy();
Hoonki Lee387663d2013-02-05 18:08:43 -0800438 wlan_hdd_tdls_free_list();
Chilam Nga75d8b62013-01-29 01:35:59 -0800439
440 vos_mem_free(pHddTdlsCtx);
441 pHddTdlsCtx = NULL;
Chilam NG571c65a2013-01-19 12:27:36 +0530442}
443
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800444/* stop all the tdls timers running */
445void wlan_hdd_tdls_timers_stop(void)
446{
447 int i;
448 struct list_head *head;
449 struct list_head *pos;
450 hddTdlsPeer_t *curr_peer;
451
452 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
453 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
454
455 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
456 {
457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
458 "%s: unable to lock list", __func__);
459 return;
460 }
461
462 for (i = 0; i < 256; i++)
463 {
464 head = &pHddTdlsCtx->peer_list[i];
465
466 list_for_each (pos, head) {
467 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
468
469 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
470 "%s: %02x:%02x:%02x:%02x:%02x:%02x -> stop idle timer",
471 __func__,
472 curr_peer->peerMac[0], curr_peer->peerMac[1],
473 curr_peer->peerMac[2], curr_peer->peerMac[3],
474 curr_peer->peerMac[4], curr_peer->peerMac[5]);
475 vos_timer_stop ( &curr_peer->peerIdleTimer );
476 }
477 }
478 mutex_unlock(&pHddTdlsCtx->lock);
479}
480
481/* destroy all the tdls timers running */
482void wlan_hdd_tdls_timers_destroy(void)
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800483{
484 int i;
485 struct list_head *head;
486 struct list_head *pos;
487 hddTdlsPeer_t *curr_peer;
488
489 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
490 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
491 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
492 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
493
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800494 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
495 {
496 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
497 "%s: unable to lock list", __func__);
498 return;
499 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800500 for (i = 0; i < 256; i++)
501 {
502 head = &pHddTdlsCtx->peer_list[i];
503
504 list_for_each (pos, head) {
505 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
506
507 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800508 "%s: %02x:%02x:%02x:%02x:%02x:%02x -> destroy idle timer",
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800509 __func__,
510 curr_peer->peerMac[0], curr_peer->peerMac[1],
511 curr_peer->peerMac[2], curr_peer->peerMac[3],
512 curr_peer->peerMac[4], curr_peer->peerMac[5]);
513 vos_timer_stop ( &curr_peer->peerIdleTimer );
514 vos_timer_destroy ( &curr_peer->peerIdleTimer );
515 }
516 }
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800517 mutex_unlock(&pHddTdlsCtx->lock);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800518}
519
Hoonki Lee387663d2013-02-05 18:08:43 -0800520/* if mac address exist, return pointer
521 if mac address doesn't exist, create a list and add, return pointer
522 return NULL if fails to get new mac address
523*/
524hddTdlsPeer_t *wlan_hdd_tdls_get_peer(u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530525{
Hoonki Lee387663d2013-02-05 18:08:43 -0800526 struct list_head *head;
527 hddTdlsPeer_t *peer;
528 u8 key;
Chilam NG571c65a2013-01-19 12:27:36 +0530529
Hoonki Lee387663d2013-02-05 18:08:43 -0800530 if (NULL == pHddTdlsCtx)
531 return NULL;
Hoonki Leebfee0342013-01-21 16:43:45 -0800532
Hoonki Lee387663d2013-02-05 18:08:43 -0800533 /* if already there, just update */
534 peer = wlan_hdd_tdls_find_peer(mac);
535 if (peer != NULL)
536 {
537 return peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530538 }
539
Hoonki Lee387663d2013-02-05 18:08:43 -0800540 /* not found, allocate and add the list */
541 peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
542 if (NULL == peer) {
543 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
544 return NULL;
545 }
Chilam NG571c65a2013-01-19 12:27:36 +0530546
Hoonki Lee387663d2013-02-05 18:08:43 -0800547 key = wlan_hdd_tdls_hash_key(mac);
548 head = &pHddTdlsCtx->peer_list[key];
Chilam NG571c65a2013-01-19 12:27:36 +0530549
Hoonki Lee387663d2013-02-05 18:08:43 -0800550 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
551 {
552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
553 "%s: unable to lock list", __func__);
554 return NULL;
555 }
Chilam NG571c65a2013-01-19 12:27:36 +0530556
Hoonki Lee387663d2013-02-05 18:08:43 -0800557 vos_mem_zero(peer, sizeof(hddTdlsPeer_t));
558 vos_mem_copy(peer->peerMac, mac, sizeof(peer->peerMac));
559
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800560 vos_timer_init(&peer->peerIdleTimer,
561 VOS_TIMER_TYPE_SW,
562 wlan_hdd_tdls_idle_cb,
563 peer);
564
Hoonki Lee387663d2013-02-05 18:08:43 -0800565 list_add_tail(&peer->node, head);
566 mutex_unlock(&pHddTdlsCtx->lock);
567
568 return peer;
569}
570
571void wlan_hdd_tdls_set_link_status(hddTdlsPeer_t *curr_peer, int status)
572{
573 if (curr_peer == NULL)
574 return;
575
576 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %02x:%02x:%02x:%02x:%02x:%02x link status to %d",
577 curr_peer->peerMac[0], curr_peer->peerMac[1],
578 curr_peer->peerMac[2], curr_peer->peerMac[3],
579 curr_peer->peerMac[4], curr_peer->peerMac[5],
580 status);
Chilam NG571c65a2013-01-19 12:27:36 +0530581
582 curr_peer->link_status = status;
583
Chilam NG571c65a2013-01-19 12:27:36 +0530584}
585
586int wlan_hdd_tdls_set_cap(u8 *mac, int cap)
587{
588 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530589
Hoonki Leebfee0342013-01-21 16:43:45 -0800590 if (NULL == pHddTdlsCtx) return -1;
591
Hoonki Lee387663d2013-02-05 18:08:43 -0800592 curr_peer = wlan_hdd_tdls_get_peer(mac);
593 if (curr_peer == NULL)
594 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530595
596 curr_peer->tdls_support = cap;
597
Hoonki Lee387663d2013-02-05 18:08:43 -0800598 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530599}
600
601int wlan_hdd_tdls_set_rssi(u8 *mac, tANI_S8 rxRssi)
602{
603 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530604
Hoonki Leebfee0342013-01-21 16:43:45 -0800605 if (NULL == pHddTdlsCtx) return -1;
606
Hoonki Lee387663d2013-02-05 18:08:43 -0800607 curr_peer = wlan_hdd_tdls_get_peer(mac);
608 if (curr_peer == NULL)
609 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530610
611 curr_peer->rssi = rxRssi;
612
Hoonki Lee387663d2013-02-05 18:08:43 -0800613 return 0;
Chilam NG571c65a2013-01-19 12:27:36 +0530614}
615
Hoonki Leea34dd892013-02-05 22:56:02 -0800616int wlan_hdd_tdls_set_responder(u8 *mac, tANI_U8 responder)
617{
618 hddTdlsPeer_t *curr_peer;
619
620 if (NULL == pHddTdlsCtx) return -1;
621
622 curr_peer = wlan_hdd_tdls_get_peer(mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800623 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800624 return -1;
625
626 curr_peer->is_responder = responder;
627
628 return 0;
629}
630
631int wlan_hdd_tdls_get_responder(u8 *mac)
632{
633 hddTdlsPeer_t *curr_peer;
634
635 if (NULL == pHddTdlsCtx) return -1;
636
637 curr_peer = wlan_hdd_tdls_find_peer(mac);
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800638 if (curr_peer == NULL)
Hoonki Leea34dd892013-02-05 22:56:02 -0800639 return -1;
640
641 return (curr_peer->is_responder);
642}
643
644
Hoonki Lee387663d2013-02-05 18:08:43 -0800645void wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
Chilam NG571c65a2013-01-19 12:27:36 +0530646{
Chilam NG571c65a2013-01-19 12:27:36 +0530647 memcpy(mac, skb->data, 6);
Chilam NG571c65a2013-01-19 12:27:36 +0530648}
649
Hoonki Lee387663d2013-02-05 18:08:43 -0800650void wlan_hdd_tdls_extract_sa(struct sk_buff *skb, u8 *mac)
Chilam Ng1279e232013-01-25 15:06:52 -0800651{
Chilam Ng1279e232013-01-25 15:06:52 -0800652 memcpy(mac, skb->data+6, 6);
Chilam Ng1279e232013-01-25 15:06:52 -0800653}
654
Hoonki Lee387663d2013-02-05 18:08:43 -0800655int wlan_hdd_tdls_increment_pkt_count(u8 *mac, u8 tx)
Chilam NG571c65a2013-01-19 12:27:36 +0530656{
Hoonki Lee387663d2013-02-05 18:08:43 -0800657 hddTdlsPeer_t *curr_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530658
Hoonki Leebfee0342013-01-21 16:43:45 -0800659 if (NULL == pHddTdlsCtx) return -1;
660
Hoonki Lee387663d2013-02-05 18:08:43 -0800661 curr_peer = wlan_hdd_tdls_get_peer(mac);
662 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +0530663 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530664
Chilam Ng1279e232013-01-25 15:06:52 -0800665 if (tx)
666 curr_peer->tx_pkt++;
667 else
668 curr_peer->rx_pkt++;
Chilam NG571c65a2013-01-19 12:27:36 +0530669
Chilam NG571c65a2013-01-19 12:27:36 +0530670 return 0;
671}
672
673int wlan_hdd_tdls_set_params(tdls_config_params_t *config)
674{
Chilam Nga75d8b62013-01-29 01:35:59 -0800675 if (NULL == pHddTdlsCtx ||
676 FALSE == tdlsImplicitTrigger) return -1;
Hoonki Leebfee0342013-01-21 16:43:45 -0800677
Chilam NG571c65a2013-01-19 12:27:36 +0530678 vos_timer_stop( &pHddTdlsCtx->peerDiscoverTimer);
679
680 vos_timer_stop( &pHddTdlsCtx->peerUpdateTimer);
681
682 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
683
684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
685 "iw set tdls params: %d %d %d %d %d %d",
686 pHddTdlsCtx->threshold_config.tx_period_t,
687 pHddTdlsCtx->threshold_config.tx_packet_n,
688 pHddTdlsCtx->threshold_config.discovery_period_t,
689 pHddTdlsCtx->threshold_config.discovery_tries_n,
690 pHddTdlsCtx->threshold_config.rx_timeout_t,
691 pHddTdlsCtx->threshold_config.rssi_hysteresis);
692
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800693 wlan_hdd_tdls_peer_reset_discovery_processed();
694
Chilam NG571c65a2013-01-19 12:27:36 +0530695 vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
696 pHddTdlsCtx->threshold_config.discovery_period_t );
697
698 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
699 pHddTdlsCtx->threshold_config.tx_period_t );
700 return 0;
701}
702
Hoonki Lee387663d2013-02-05 18:08:43 -0800703int wlan_hdd_tdls_set_sta_id(u8 *mac, u8 staId)
Kiran V1ccee932012-12-12 14:49:46 -0800704{
Hoonki Lee387663d2013-02-05 18:08:43 -0800705 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -0800706
Hoonki Leebfee0342013-01-21 16:43:45 -0800707 if (NULL == pHddTdlsCtx) return -1;
708
Hoonki Lee387663d2013-02-05 18:08:43 -0800709 curr_peer = wlan_hdd_tdls_get_peer(mac);
710 if (curr_peer == NULL)
Chilam NG571c65a2013-01-19 12:27:36 +0530711 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530712
Hoonki Lee387663d2013-02-05 18:08:43 -0800713 curr_peer->staId = staId;
Chilam NG571c65a2013-01-19 12:27:36 +0530714
715 return 0;
Kiran V1ccee932012-12-12 14:49:46 -0800716}
717
Hoonki Lee387663d2013-02-05 18:08:43 -0800718/* if peerMac is found, then it returns pointer to hddTdlsPeer_t
719 otherwise, it returns NULL
720*/
721hddTdlsPeer_t *wlan_hdd_tdls_find_peer(u8 *mac)
Kiran V1ccee932012-12-12 14:49:46 -0800722{
Hoonki Lee387663d2013-02-05 18:08:43 -0800723 u8 key;
724 struct list_head *pos;
725 struct list_head *head;
726 hddTdlsPeer_t *curr_peer;
727
728 if (NULL == pHddTdlsCtx)
729 return NULL;
730
731 key = wlan_hdd_tdls_hash_key(mac);
732
733 head = &pHddTdlsCtx->peer_list[key];
734
735 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
736 {
737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
738 "%s: unable to lock list", __func__);
739 return NULL;
740 }
741
742 list_for_each(pos, head) {
743 curr_peer = list_entry (pos, hddTdlsPeer_t, node);
744 if (!memcmp(mac, curr_peer->peerMac, 6)) {
745 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
746 "findTdlsPeer: found staId %d", curr_peer->staId);
747 mutex_unlock(&pHddTdlsCtx->lock);
748 return curr_peer;
749 }
750 }
751
752 mutex_unlock(&pHddTdlsCtx->lock);
753 return NULL;
754}
755
756int wlan_hdd_tdls_reset_peer(u8 *mac)
757{
Chilam NG571c65a2013-01-19 12:27:36 +0530758 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -0800759
Hoonki Leebfee0342013-01-21 16:43:45 -0800760 if (NULL == pHddTdlsCtx) return -1;
761
Hoonki Lee387663d2013-02-05 18:08:43 -0800762 curr_peer = wlan_hdd_tdls_get_peer(mac);
763 if (curr_peer == NULL)
764 return -1;
Chilam NG571c65a2013-01-19 12:27:36 +0530765
Hoonki Leecdd8e962013-01-20 00:45:46 -0800766 curr_peer->link_status = eTDLS_LINK_NOT_CONNECTED;
767 curr_peer->staId = 0;
768 curr_peer->rssi = -120;
Hoonki Lee387663d2013-02-05 18:08:43 -0800769
770 if (FALSE != tdlsImplicitTrigger) {
Chilam Nga75d8b62013-01-29 01:35:59 -0800771 vos_timer_stop( &curr_peer->peerIdleTimer );
Chilam Nga75d8b62013-01-29 01:35:59 -0800772 }
Hoonki Lee387663d2013-02-05 18:08:43 -0800773 return 0;
Hoonki Leecdd8e962013-01-20 00:45:46 -0800774}
775
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800776static tANI_S32 wlan_hdd_tdls_peer_reset_discovery_processed(void)
777{
778 int i;
779 struct list_head *head;
780 hddTdlsPeer_t *tmp;
781 struct list_head *pos, *q;
782
783 if (NULL == pHddTdlsCtx) return -1;
784
785 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
786 {
787 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
788 "%s: unable to lock list", __func__);
789 return -1;
790 }
791
792 pHddTdlsCtx->discovery_peer_cnt = 0;
793
794 for (i = 0; i < 256; i++) {
795 head = &pHddTdlsCtx->peer_list[i];
796 list_for_each_safe (pos, q, head) {
797 tmp = list_entry(pos, hddTdlsPeer_t, node);
798 tmp->discovery_processed = 0;
799 }
800 }
801 mutex_unlock(&pHddTdlsCtx->lock);
802
803 return 0;
804}
805
806static tANI_S32 wlan_hdd_get_tdls_discovery_peer_cnt(void)
807{
808 int i;
809 struct list_head *head;
810 struct list_head *pos, *q;
811 int discovery_peer_cnt=0;
812 hddTdlsPeer_t *tmp;
813
814 if (NULL == pHddTdlsCtx) return -1;
815
816 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
817 {
818 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
819 "%s: unable to lock list", __func__);
820 return -1;
821 }
822
823 for (i = 0; i < 256; i++) {
824 head = &pHddTdlsCtx->peer_list[i];
825 list_for_each_safe (pos, q, head) {
826 tmp = list_entry(pos, hddTdlsPeer_t, node);
827 VOS_TRACE(VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
828 "%s, %d, %02x:%02x:%02x:%02x:%02x:%02x", __func__, i,
829 tmp->peerMac[0],
830 tmp->peerMac[1],
831 tmp->peerMac[2],
832 tmp->peerMac[3],
833 tmp->peerMac[4],
834 tmp->peerMac[5]);
835 discovery_peer_cnt++;
836 }
837 }
838 mutex_unlock(&pHddTdlsCtx->lock);
839
840 return discovery_peer_cnt;
841}
842
Lee Hoonkic1262f22013-01-24 21:59:00 -0800843/* TODO: Currently I am using conn_info.staId
844 here as per current design but tdls.c shouldn't
845 have touch this.*/
846u8 wlan_hdd_tdlsConnectedPeers(void)
847{
848 hdd_adapter_t *pAdapter;
849 hdd_station_ctx_t *pHddStaCtx;
850 u8 staIdx;
851 u8 count = 0;
852
853 if (NULL == pHddTdlsCtx) return -1;
854
855 pAdapter = WLAN_HDD_GET_PRIV_PTR(pHddTdlsCtx->dev);
856 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
857
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -0800858 /* 0 staIdx is assigned to AP we dont want to touch that */
859 for (staIdx = 1 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Lee Hoonkic1262f22013-01-24 21:59:00 -0800860 {
861 if (0 != pHddStaCtx->conn_info.staId[staIdx] )
862 count++;
863 }
864 return count;
865}
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800866
867int wlan_hdd_tdls_get_all_peers(char *buf, int buflen)
868{
869 int i;
870 int len, init_len;
Hoonki Lee387663d2013-02-05 18:08:43 -0800871 struct list_head *head;
872 struct list_head *pos;
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800873 hddTdlsPeer_t *curr_peer;
874
875 if (NULL == pHddTdlsCtx) {
876 len = snprintf(buf, buflen, "TDLS not enabled\n");
877 return len;
878 }
879
880 init_len = buflen;
881 len = snprintf(buf, buflen, "\n%-18s%-3s%-4s%-3s%-5s\n", "MAC", "Id", "cap", "up", "RSSI");
882 buf += len;
883 buflen -= len;
884 /* 1234567890123456789012345678901234567 */
885 len = snprintf(buf, buflen, "---------------------------------\n");
886 buf += len;
887 buflen -= len;
888
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800889 if (mutex_lock_interruptible(&pHddTdlsCtx->lock))
890 {
891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
892 "%s: unable to lock list", __func__);
893 return init_len-buflen;
894 }
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800895 for (i = 0; i < 256; i++) {
Hoonki Lee387663d2013-02-05 18:08:43 -0800896 head = &pHddTdlsCtx->peer_list[i];
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800897
Hoonki Lee387663d2013-02-05 18:08:43 -0800898 list_for_each(pos, head) {
899 curr_peer= list_entry (pos, hddTdlsPeer_t, node);
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800900
Hoonki Lee387663d2013-02-05 18:08:43 -0800901 if (buflen < 32+1)
902 break;
903 len = snprintf(buf, buflen,
904 "%02x:%02x:%02x:%02x:%02x:%02x%3d%4s%3s%5d\n",
905 curr_peer->peerMac[0], curr_peer->peerMac[1],
906 curr_peer->peerMac[2], curr_peer->peerMac[3],
907 curr_peer->peerMac[4], curr_peer->peerMac[5],
908 curr_peer->staId,
909 (curr_peer->tdls_support == eTDLS_CAP_SUPPORTED) ? "Y":"N",
910 (curr_peer->link_status == eTDLS_LINK_CONNECTED) ? "Y":"N",
911 curr_peer->rssi);
912 buf += len;
913 buflen -= len;
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800914 }
915 }
Gopichand Nakkala91b09262013-02-10 14:27:02 -0800916 mutex_unlock(&pHddTdlsCtx->lock);
Chilam Ng16a2a1c2013-01-29 01:27:29 -0800917 return init_len-buflen;
918}
Gopichand Nakkalac3694582013-02-13 20:51:22 -0800919
920void wlan_hdd_tdls_connection_callback(hdd_adapter_t *pAdapter)
921{
922 if (NULL == pHddTdlsCtx) return;
923
924 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,
925 "%s, update %d discover %d", __func__,
926 pHddTdlsCtx->threshold_config.tx_period_t,
927 pHddTdlsCtx->threshold_config.discovery_period_t);
928
929 wlan_hdd_tdls_peer_reset_discovery_processed();
930
931 vos_timer_start(&pHddTdlsCtx->peerDiscoverTimer,
932 pHddTdlsCtx->threshold_config.discovery_period_t);
933
934
935 vos_timer_start(&pHddTdlsCtx->peerUpdateTimer,
936 pHddTdlsCtx->threshold_config.tx_period_t);
937
938}
939
940void wlan_hdd_tdls_disconnection_callback(hdd_adapter_t *pAdapter)
941{
942 if (NULL == pHddTdlsCtx) return;
943
944 VOS_TRACE( VOS_MODULE_ID_HDD, TDLS_LOG_LEVEL,"%s", __func__);
945
946 wlan_hdd_tdls_timers_stop();
947 wlan_hdd_tdls_free_list();
948}