blob: 26039614e0f03b0c6886b69560d4522447ce6641 [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
42typedef struct {
43 struct list_head node;
Kiran V1ccee932012-12-12 14:49:46 -080044 tSirMacAddr peerMac;
Chilam NG571c65a2013-01-19 12:27:36 +053045 tANI_U16 staId ;
46 tANI_S8 rssi;
47 tANI_S8 tdls_support;
48 tANI_S8 link_status;
49 tANI_U16 discovery_attempt;
50 tANI_U16 tx_pkt;
51} hddTdlsPeer_t;
Kiran V1ccee932012-12-12 14:49:46 -080052
Kiran V1ccee932012-12-12 14:49:46 -080053
Chilam NG571c65a2013-01-19 12:27:36 +053054typedef struct {
55 hddTdlsPeer_t* peer_list[256];
56 struct net_device *dev;
57 spinlock_t lock;
58 vos_timer_t peerDiscoverTimer;
59 vos_timer_t peerUpdateTimer;
60 vos_timer_t peerIdleTimer;
61 tdls_config_params_t threshold_config;
62 tANI_S8 ap_rssi;
63} tdlsCtx_t;
64
65tdlsCtx_t *pHddTdlsCtx;
66
Hoonki Leecdd8e962013-01-20 00:45:46 -080067void wlan_hdd_freeTdlsPeer(void);
Chilam NG571c65a2013-01-19 12:27:36 +053068
69static v_VOID_t wlan_hdd_discover_peer_cb( v_PVOID_t userData )
Hoonki Leef63df0d2013-01-16 19:29:14 -080070{
71 int i;
Chilam NG571c65a2013-01-19 12:27:36 +053072 hddTdlsPeer_t *curr_peer;
73 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(pHddTdlsCtx->dev);
74 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Hoonki Leef63df0d2013-01-16 19:29:14 -080075
Chilam NG571c65a2013-01-19 12:27:36 +053076 for (i = 0; i < 256; i++) {
77 curr_peer = pHddTdlsCtx->peer_list[i];
78 if (NULL == curr_peer) continue;
79
80 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
81 "hdd discovery cb - %d: %x %x %x %x %x %x\n", i,
82 curr_peer->peerMac[0],
83 curr_peer->peerMac[1],
84 curr_peer->peerMac[2],
85 curr_peer->peerMac[3],
86 curr_peer->peerMac[4],
87 curr_peer->peerMac[5]);
88
89 do {
90 if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) &&
91 (eTDLS_LINK_NOT_CONNECTED == curr_peer->link_status) &&
92 (curr_peer->discovery_attempt <
93 pHddTdlsCtx->threshold_config.discovery_tries_n)) {
94 wlan_hdd_cfg80211_send_tdls_discover_req(pHddCtx->wiphy,
95 pHddTdlsCtx->dev, curr_peer->peerMac);
96// cfg80211_tdls_oper_request(pHddTdlsCtx->dev, curr_peer->peerMac,
97// NL80211_TDLS_DISCOVERY_REQ, FALSE, GFP_KERNEL);
98
99// if (++curr_peer->discovery_attempt >= pHddTdlsCtx->threshold_config.discovery_tries_n) {
100// curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED;
101// }
102 }
103
104 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
105 } while (&curr_peer->node != curr_peer->node.next);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800106 }
107
Chilam NG571c65a2013-01-19 12:27:36 +0530108 vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
109 pHddTdlsCtx->threshold_config.discovery_period_t );
110
111 wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi);
112
113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d",
114 pHddTdlsCtx->ap_rssi);
Hoonki Leef63df0d2013-01-16 19:29:14 -0800115}
Chilam NG571c65a2013-01-19 12:27:36 +0530116
117static v_VOID_t wlan_hdd_update_peer_cb( v_PVOID_t userData )
118{
119 int i;
120 hddTdlsPeer_t *curr_peer;
121
122 for (i = 0; i < 256; i++) {
123 curr_peer = pHddTdlsCtx->peer_list[i];
124 if (NULL == curr_peer) continue;
125
126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
127 "hdd update cb - %d: %x %x %x %x %x %x -> %d\n", i,
128 curr_peer->peerMac[0],
129 curr_peer->peerMac[1],
130 curr_peer->peerMac[2],
131 curr_peer->peerMac[3],
132 curr_peer->peerMac[4],
133 curr_peer->peerMac[5],
134 curr_peer->tx_pkt);
135
136 do {
137 if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) {
138 if (eTDLS_LINK_CONNECTED != curr_peer->link_status) {
139 if (curr_peer->tx_pkt >=
140 pHddTdlsCtx->threshold_config.tx_packet_n) {
141#ifdef CONFIG_TDLS_IMPLICIT
142 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
143 curr_peer->peerMac,
144 NL80211_TDLS_SETUP, FALSE,
145 GFP_KERNEL);
146#endif
Hoonki Leecdd8e962013-01-20 00:45:46 -0800147 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530148 }
149
Hoonki Leecdd8e962013-01-20 00:45:46 -0800150 if ((tANI_S32)curr_peer->rssi >
151 (tANI_S32)(pHddTdlsCtx->threshold_config.rssi_hysteresis +
Chilam NG571c65a2013-01-19 12:27:36 +0530152 pHddTdlsCtx->ap_rssi)) {
153
154 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
155 "RSSI triggering");
156
157#ifdef CONFIG_TDLS_IMPLICIT
158 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
159 curr_peer->peerMac,
160 NL80211_TDLS_SETUP, FALSE,
161 GFP_KERNEL);
162#endif
163 }
164 } else {
Hoonki Leecdd8e962013-01-20 00:45:46 -0800165 if (curr_peer->tx_pkt <
166 pHddTdlsCtx->threshold_config.tx_packet_n) {
Chilam NG571c65a2013-01-19 12:27:36 +0530167 cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
168 curr_peer->peerMac,
169 NL80211_TDLS_TEARDOWN, FALSE,
170 GFP_KERNEL);
Hoonki Leecdd8e962013-01-20 00:45:46 -0800171
172 goto next_peer;
Chilam NG571c65a2013-01-19 12:27:36 +0530173 }
Hoonki Leecdd8e962013-01-20 00:45:46 -0800174
175// if (curr_peer->rssi <
176// (pHddTdlsCtx->threshold_config.rssi_hysteresis +
177// pHddTdlsCtx->ap_rssi)) {
178//
179//#ifdef CONFIG_TDLS_IMPLICIT
180// cfg80211_tdls_oper_request(pHddTdlsCtx->dev,
181// curr_peer->peerMac,
182// NL80211_TDLS_TEARDOWN, FALSE,
183// GFP_KERNEL);
184//#endif
185// }
Chilam NG571c65a2013-01-19 12:27:36 +0530186 }
187 }
188
Hoonki Leecdd8e962013-01-20 00:45:46 -0800189next_peer:
Chilam NG571c65a2013-01-19 12:27:36 +0530190 curr_peer->tx_pkt = 0;
191
192 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
193 } while (&curr_peer->node != curr_peer->node.next);
194 }
195
196 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
197 pHddTdlsCtx->threshold_config.tx_period_t );
198}
199
200int wlan_hdd_tdls_init(struct net_device *dev)
201{
202 VOS_STATUS status;
Hoonki Leebf870f32013-01-19 15:53:30 +0530203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
204 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
Chilam NG571c65a2013-01-19 12:27:36 +0530205
Hoonki Leebf870f32013-01-19 15:53:30 +0530206 if(FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport)
207 {
208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS not enabled!", __func__);
209 return -1;
210 }
211
212 pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t));
Chilam NG571c65a2013-01-19 12:27:36 +0530213 if (NULL == pHddTdlsCtx) {
214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__);
215 return -1;
216 }
217
218 vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t));
219
220 pHddTdlsCtx->dev = dev;
221
Hoonki Leebf870f32013-01-19 15:53:30 +0530222 if(FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger)
223 {
224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s TDLS Implicit trigger not enabled!", __func__);
225 return -1;
226 }
227 pHddTdlsCtx->threshold_config.tx_period_t = pHddCtx->cfg_ini->fTDLSTxStatsPeriod;
228 pHddTdlsCtx->threshold_config.tx_packet_n = pHddCtx->cfg_ini->fTDLSTxPacketThreshold;
229 pHddTdlsCtx->threshold_config.discovery_period_t = pHddCtx->cfg_ini->fTDLSDiscoveryPeriod;
230 pHddTdlsCtx->threshold_config.discovery_tries_n = pHddCtx->cfg_ini->fTDLSMaxDiscoveryAttempt;
231 pHddTdlsCtx->threshold_config.rx_timeout_t = pHddCtx->cfg_ini->fTDLSRxIdleTimeout;
232 pHddTdlsCtx->threshold_config.rssi_hysteresis = pHddCtx->cfg_ini->fTDLSRssiHysteresis;
Chilam NG571c65a2013-01-19 12:27:36 +0530233
234 status = vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer,
235 VOS_TIMER_TYPE_SW,
236 wlan_hdd_discover_peer_cb,
237 pHddTdlsCtx);
238
239 status = vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
240 pHddTdlsCtx->threshold_config.discovery_period_t );
241
242 status = vos_timer_init(&pHddTdlsCtx->peerUpdateTimer,
243 VOS_TIMER_TYPE_SW,
244 wlan_hdd_update_peer_cb,
245 pHddTdlsCtx);
246
247 status = vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
248 pHddTdlsCtx->threshold_config.tx_period_t );
249
250 return 0;
251}
252
253void wlan_hdd_tdls_exit()
254{
255 vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer);
256 vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer);
257 vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer);
258 vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer);
Hoonki Leecdd8e962013-01-20 00:45:46 -0800259
260 wlan_hdd_freeTdlsPeer();
261 if(pHddTdlsCtx)
262 vos_mem_free(pHddTdlsCtx);
Chilam NG571c65a2013-01-19 12:27:36 +0530263}
264
265int wlan_hdd_tdls_set_link_status(u8 *mac, int status)
266{
267 hddTdlsPeer_t *curr_peer;
268 int i;
269 u8 key = 0;
270
271 for (i = 0; i < 6; i++)
272 key ^= mac[i];
273
274 curr_peer = pHddTdlsCtx->peer_list[key];
275
276 if (NULL == curr_peer) {
277 hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC!", __func__);
278 return -1;
279 }
280
281 do {
282 if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer;
283 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
284 } while (&curr_peer->node != curr_peer->node.next);
285
286 hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC!", __func__);
287 return -1;
288
289found_peer:
290
291 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d link status to %d",
292 key, status);
293
294 curr_peer->link_status = status;
295
296 return status;
297}
298
299int wlan_hdd_tdls_set_cap(u8 *mac, int cap)
300{
301 hddTdlsPeer_t *curr_peer;
302 int i;
303 u8 key = 0;
304
305 for (i = 0; i < 6; i++)
306 key ^= mac[i];
307
308 curr_peer = pHddTdlsCtx->peer_list[key];
309
310 if (NULL == curr_peer) {
311 curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
312
313 if (NULL == curr_peer) {
314 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
315 return -1;
316 }
317 vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t));
318
319 INIT_LIST_HEAD(&curr_peer->node);
320 memcpy(curr_peer->peerMac, mac, 6);
321 curr_peer->tdls_support = cap;
322 pHddTdlsCtx->peer_list[key] = curr_peer;
323
324 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
325 "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x",
326 key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
327 curr_peer );
328 return 0;
329 }
330
331 do {
332 if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer;
333 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
334 } while (&curr_peer->node != curr_peer->node.next);
335
336 hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC %d: %x %x %x %x %x %x",
337 __func__, key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
338
339 return -1;
340
341found_peer:
342
343 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d support cap to %d",
344 key, cap);
345
346 curr_peer->tdls_support = cap;
347
348 return cap;
349}
350
351int wlan_hdd_tdls_set_rssi(u8 *mac, tANI_S8 rxRssi)
352{
353 hddTdlsPeer_t *curr_peer;
354 int i;
355 u8 key = 0;
356
357 for (i = 0; i < 6; i++)
358 key ^= mac[i];
359
360 curr_peer = pHddTdlsCtx->peer_list[key];
361
362 if (NULL == curr_peer) {
363 curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
364
365 if (NULL == curr_peer) {
366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
367 return -1;
368 }
369 vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t));
370
371 INIT_LIST_HEAD(&curr_peer->node);
372 memcpy(curr_peer->peerMac, mac, 6);
373 curr_peer->rssi = rxRssi;
374 pHddTdlsCtx->peer_list[key] = curr_peer;
375
376 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
377 "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x",
378 key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
379 curr_peer );
380 return 0;
381 }
382
383 do {
384 if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer;
385 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
386 } while (&curr_peer->node != curr_peer->node.next);
387
388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC %d: %x %x %x %x %x %x",
389 __func__, key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
390
391 return -1;
392
393found_peer:
394
395 hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d rssi to %d",
396 key, rxRssi);
397
398 curr_peer->rssi = rxRssi;
399
400 return rxRssi;
401}
402
403u8 wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac)
404{
405 int i;
406 u8 hash = 0;
407
408 memcpy(mac, skb->data, 6);
409 for (i = 0; i < 6; i++)
410 hash ^= mac[i];
411
412 return hash;
413}
414
415int wlan_hdd_tdls_add_peer_to_list(u8 key, u8 *mac)
416{
417 hddTdlsPeer_t *new_peer, *curr_peer;
418
419 curr_peer = pHddTdlsCtx->peer_list[key];
420
421 if (NULL == curr_peer) {
422 curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
423
424 if (NULL == curr_peer) {
425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
426 return -1;
427 }
428 vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t));
429 curr_peer->rssi = -120;
430
431 INIT_LIST_HEAD(&curr_peer->node);
432 memcpy(curr_peer->peerMac, mac, 6);
433
434 pHddTdlsCtx->peer_list[key] = curr_peer;
435
436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
437 "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x",
438 key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
439 curr_peer );
440 return 0;
441 }
442
443 do {
444 if (!memcmp(mac, curr_peer->peerMac, 6)) goto known_peer;
445 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
446 } while (&curr_peer->node != curr_peer->node.next);
447
448 new_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
449 if (NULL == new_peer) {
450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__);
451 return -1;
452 }
453 vos_mem_zero(new_peer, sizeof(hddTdlsPeer_t));
454 curr_peer->rssi = -120;
455 memcpy(new_peer->peerMac, mac, 6);
456
457 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
458 "add peer - key:%d, mac:%x %x %x %x %x %x",
459 key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
460
461 list_add(&new_peer->node, &curr_peer->node);
462 curr_peer = new_peer;
463
464known_peer:
465 curr_peer->tx_pkt++;
466
467 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
468 "known peer - key:%d, mac:%x %x %x %x %x %x, tx:%d",
469 key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
470 curr_peer->tx_pkt );
471
472 return 0;
473}
474
475int wlan_hdd_tdls_set_params(tdls_config_params_t *config)
476{
477 vos_timer_stop( &pHddTdlsCtx->peerDiscoverTimer);
478
479 vos_timer_stop( &pHddTdlsCtx->peerUpdateTimer);
480
481 memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t));
482
483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
484 "iw set tdls params: %d %d %d %d %d %d",
485 pHddTdlsCtx->threshold_config.tx_period_t,
486 pHddTdlsCtx->threshold_config.tx_packet_n,
487 pHddTdlsCtx->threshold_config.discovery_period_t,
488 pHddTdlsCtx->threshold_config.discovery_tries_n,
489 pHddTdlsCtx->threshold_config.rx_timeout_t,
490 pHddTdlsCtx->threshold_config.rssi_hysteresis);
491
492 vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer,
493 pHddTdlsCtx->threshold_config.discovery_period_t );
494
495 vos_timer_start( &pHddTdlsCtx->peerUpdateTimer,
496 pHddTdlsCtx->threshold_config.tx_period_t );
497 return 0;
498}
499
Kiran V1ccee932012-12-12 14:49:46 -0800500int wlan_hdd_saveTdlsPeer(tCsrRoamInfo *pRoamInfo)
501{
Chilam NG571c65a2013-01-19 12:27:36 +0530502 hddTdlsPeer_t *new_peer, *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -0800503 int i;
Chilam NG571c65a2013-01-19 12:27:36 +0530504 u8 key = 0;
Kiran V1ccee932012-12-12 14:49:46 -0800505
Chilam NG571c65a2013-01-19 12:27:36 +0530506 for (i = 0; i < 6; i++)
507 key ^= pRoamInfo->peerMac[i];
Kiran V1ccee932012-12-12 14:49:46 -0800508
Chilam NG571c65a2013-01-19 12:27:36 +0530509 curr_peer = pHddTdlsCtx->peer_list[key];
Kiran V1ccee932012-12-12 14:49:46 -0800510
Chilam NG571c65a2013-01-19 12:27:36 +0530511 if (NULL == curr_peer) {
512 curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
513
514 if (NULL == curr_peer) {
515 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
516 "saveTdlsPeer: NOT saving staId %d", pRoamInfo->staId);
517 return -1;
518 }
519 vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t));
520
521 INIT_LIST_HEAD(&curr_peer->node);
522 memcpy(curr_peer->peerMac, pRoamInfo->peerMac, 6);
523 curr_peer->staId = pRoamInfo->staId;
524 pHddTdlsCtx->peer_list[key] = curr_peer;
525
526 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Kiran V1ccee932012-12-12 14:49:46 -0800527 "saveTdlsPeer: saved staId %d", pRoamInfo->staId);
Chilam NG571c65a2013-01-19 12:27:36 +0530528 return 0;
Kiran V1ccee932012-12-12 14:49:46 -0800529 }
530
Chilam NG571c65a2013-01-19 12:27:36 +0530531 do {
532 if (!memcmp(pRoamInfo->peerMac, curr_peer->peerMac, 6)) goto known_peer;
533 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
534 } while (&curr_peer->node != curr_peer->node.next);
535
536 new_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t));
537 if (NULL == new_peer) {
538 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
539 "saveTdlsPeer: NOT saving staId %d", pRoamInfo->staId);
540 return -1;
541 }
542 vos_mem_zero(new_peer, sizeof(hddTdlsPeer_t));
543
544 list_add(&new_peer->node, &curr_peer->node);
545 curr_peer = new_peer;
546
547known_peer:
548 memcpy(curr_peer->peerMac, pRoamInfo->peerMac, 6);
549 curr_peer->staId = pRoamInfo->staId;
550
551 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
552 "saveTdlsPeer: saved staId %d", pRoamInfo->staId);
553
554 return 0;
Kiran V1ccee932012-12-12 14:49:46 -0800555}
556
557int wlan_hdd_findTdlsPeer(tSirMacAddr peerMac)
558{
559 int i;
Chilam NG571c65a2013-01-19 12:27:36 +0530560 hddTdlsPeer_t *curr_peer;
Kiran V1ccee932012-12-12 14:49:46 -0800561
Chilam NG571c65a2013-01-19 12:27:36 +0530562 for (i = 0; i < 256; i++) {
563 curr_peer = pHddTdlsCtx->peer_list[i];
564 if (NULL == curr_peer) continue;
565
566 do {
567 if (!memcmp(peerMac, curr_peer->peerMac, 6)) {
568 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
569 "findTdlsPeer: found staId %d", curr_peer->staId);
570 return curr_peer->staId;
571 }
572
573 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
574 } while (&curr_peer->node != curr_peer->node.next);
Kiran V1ccee932012-12-12 14:49:46 -0800575 }
576
Chilam NG571c65a2013-01-19 12:27:36 +0530577 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
578 "findTdlsPeer: staId NOT found");
Kiran V1ccee932012-12-12 14:49:46 -0800579
Kiran V1ccee932012-12-12 14:49:46 -0800580 return -1;
581}
Chilam NG571c65a2013-01-19 12:27:36 +0530582
583void wlan_hdd_removeTdlsPeer(tCsrRoamInfo *pRoamInfo)
584{
585 int i;
586 hddTdlsPeer_t *curr_peer;
587
588 for (i = 0; i < 256; i++) {
589
590 curr_peer = pHddTdlsCtx->peer_list[i];
591
592 if (NULL == curr_peer) continue;
593
594 do {
595 if (curr_peer->staId == pRoamInfo->staId) goto found_peer;
596
597 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
598 } while (&curr_peer->node != curr_peer->node.next);
599 }
600
601 if (i == 256) return;
602
603found_peer:
Hoonki Leecdd8e962013-01-20 00:45:46 -0800604 curr_peer->link_status = eTDLS_LINK_NOT_CONNECTED;
605 curr_peer->staId = 0;
606 curr_peer->rssi = -120;
607}
608
609void wlan_hdd_freeTdlsPeer(void)
610{
611 int i;
612 hddTdlsPeer_t *curr_peer;
613 hddTdlsPeer_t *temp_peer;
614
615 for (i = 0; i < 256; i++) {
616
617 curr_peer = pHddTdlsCtx->peer_list[i];
618
619 if (NULL != curr_peer) {
620 do {
621 temp_peer = curr_peer;
622 curr_peer = (hddTdlsPeer_t *)curr_peer->node.next;
623 vos_mem_free(temp_peer);
624
625 } while (&curr_peer->node != curr_peer->node.next);
626 }
627 }
Chilam NG571c65a2013-01-19 12:27:36 +0530628}