| /* |
| * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. |
| * |
| * Previously licensed under the ISC license by Qualcomm Atheros, Inc. |
| * |
| * |
| * Permission to use, copy, modify, and/or distribute this software for |
| * any purpose with or without fee is hereby granted, provided that the |
| * above copyright notice and this permission notice appear in all |
| * copies. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
| * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
| * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
| * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR |
| * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
| * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
| * PERFORMANCE OF THIS SOFTWARE. |
| */ |
| |
| /**======================================================================== |
| |
| \file wlan_hdd_tdls.c |
| |
| \brief WLAN Host Device Driver implementation for TDLS |
| |
| ========================================================================*/ |
| |
| #include <wlan_hdd_includes.h> |
| #include <wlan_hdd_hostapd.h> |
| #include <net/cfg80211.h> |
| #include <linux/netdevice.h> |
| #include <linux/skbuff.h> |
| #include <linux/list.h> |
| #include <linux/etherdevice.h> |
| #include <net/ieee80211_radiotap.h> |
| #include "wlan_hdd_tdls.h" |
| #include "wlan_hdd_cfg80211.h" |
| |
| |
| typedef struct { |
| struct list_head node; |
| tSirMacAddr peerMac; |
| tANI_U16 staId ; |
| tANI_S8 rssi; |
| tANI_S8 tdls_support; |
| tANI_S8 link_status; |
| tANI_U16 discovery_attempt; |
| tANI_U16 tx_pkt; |
| } hddTdlsPeer_t; |
| |
| |
| typedef struct { |
| hddTdlsPeer_t* peer_list[256]; |
| struct net_device *dev; |
| spinlock_t lock; |
| vos_timer_t peerDiscoverTimer; |
| vos_timer_t peerUpdateTimer; |
| vos_timer_t peerIdleTimer; |
| tdls_config_params_t threshold_config; |
| tANI_S8 ap_rssi; |
| } tdlsCtx_t; |
| |
| tdlsCtx_t *pHddTdlsCtx; |
| |
| |
| static v_VOID_t wlan_hdd_discover_peer_cb( v_PVOID_t userData ) |
| { |
| int i; |
| hddTdlsPeer_t *curr_peer; |
| hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(pHddTdlsCtx->dev); |
| hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); |
| |
| for (i = 0; i < 256; i++) { |
| curr_peer = pHddTdlsCtx->peer_list[i]; |
| if (NULL == curr_peer) continue; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "hdd discovery cb - %d: %x %x %x %x %x %x\n", i, |
| curr_peer->peerMac[0], |
| curr_peer->peerMac[1], |
| curr_peer->peerMac[2], |
| curr_peer->peerMac[3], |
| curr_peer->peerMac[4], |
| curr_peer->peerMac[5]); |
| |
| do { |
| if ((eTDLS_CAP_UNKNOWN == curr_peer->tdls_support) && |
| (eTDLS_LINK_NOT_CONNECTED == curr_peer->link_status) && |
| (curr_peer->discovery_attempt < |
| pHddTdlsCtx->threshold_config.discovery_tries_n)) { |
| wlan_hdd_cfg80211_send_tdls_discover_req(pHddCtx->wiphy, |
| pHddTdlsCtx->dev, curr_peer->peerMac); |
| // cfg80211_tdls_oper_request(pHddTdlsCtx->dev, curr_peer->peerMac, |
| // NL80211_TDLS_DISCOVERY_REQ, FALSE, GFP_KERNEL); |
| |
| // if (++curr_peer->discovery_attempt >= pHddTdlsCtx->threshold_config.discovery_tries_n) { |
| // curr_peer->tdls_support = eTDLS_CAP_NOT_SUPPORTED; |
| // } |
| } |
| |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| } |
| |
| vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer, |
| pHddTdlsCtx->threshold_config.discovery_period_t ); |
| |
| wlan_hdd_get_rssi(pAdapter, &pHddTdlsCtx->ap_rssi); |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "beacon rssi: %d", |
| pHddTdlsCtx->ap_rssi); |
| } |
| |
| static v_VOID_t wlan_hdd_update_peer_cb( v_PVOID_t userData ) |
| { |
| int i; |
| hddTdlsPeer_t *curr_peer; |
| |
| for (i = 0; i < 256; i++) { |
| curr_peer = pHddTdlsCtx->peer_list[i]; |
| if (NULL == curr_peer) continue; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "hdd update cb - %d: %x %x %x %x %x %x -> %d\n", i, |
| curr_peer->peerMac[0], |
| curr_peer->peerMac[1], |
| curr_peer->peerMac[2], |
| curr_peer->peerMac[3], |
| curr_peer->peerMac[4], |
| curr_peer->peerMac[5], |
| curr_peer->tx_pkt); |
| |
| do { |
| if (eTDLS_CAP_SUPPORTED == curr_peer->tdls_support) { |
| if (eTDLS_LINK_CONNECTED != curr_peer->link_status) { |
| if (curr_peer->tx_pkt >= |
| pHddTdlsCtx->threshold_config.tx_packet_n) { |
| #ifdef CONFIG_TDLS_IMPLICIT |
| cfg80211_tdls_oper_request(pHddTdlsCtx->dev, |
| curr_peer->peerMac, |
| NL80211_TDLS_SETUP, FALSE, |
| GFP_KERNEL); |
| #endif |
| } |
| |
| if (curr_peer->rssi > |
| (pHddTdlsCtx->threshold_config.rssi_hysteresis + |
| pHddTdlsCtx->ap_rssi)) { |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "RSSI triggering"); |
| |
| #ifdef CONFIG_TDLS_IMPLICIT |
| cfg80211_tdls_oper_request(pHddTdlsCtx->dev, |
| curr_peer->peerMac, |
| NL80211_TDLS_SETUP, FALSE, |
| GFP_KERNEL); |
| #endif |
| } |
| } else { |
| if (curr_peer->rssi < |
| (pHddTdlsCtx->threshold_config.rssi_hysteresis + |
| pHddTdlsCtx->ap_rssi)) { |
| |
| #ifdef CONFIG_TDLS_IMPLICIT |
| cfg80211_tdls_oper_request(pHddTdlsCtx->dev, |
| curr_peer->peerMac, |
| NL80211_TDLS_TEARDOWN, FALSE, |
| GFP_KERNEL); |
| #endif |
| } |
| } |
| } |
| |
| curr_peer->tx_pkt = 0; |
| |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| } |
| |
| vos_timer_start( &pHddTdlsCtx->peerUpdateTimer, |
| pHddTdlsCtx->threshold_config.tx_period_t ); |
| } |
| |
| int wlan_hdd_tdls_init(struct net_device *dev) |
| { |
| VOS_STATUS status; |
| pHddTdlsCtx = vos_mem_malloc(sizeof(tdlsCtx_t)); |
| |
| if (NULL == pHddTdlsCtx) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s malloc failed!", __func__); |
| return -1; |
| } |
| |
| vos_mem_zero(pHddTdlsCtx, sizeof(tdlsCtx_t)); |
| |
| pHddTdlsCtx->dev = dev; |
| |
| pHddTdlsCtx->threshold_config.tx_period_t = TDLS_TX_STATS_PERIOD; |
| pHddTdlsCtx->threshold_config.tx_packet_n = TDLS_IMPLICIT_TRIGGER_PKT_THRESHOLD; |
| pHddTdlsCtx->threshold_config.discovery_period_t = TDLS_DISCOVERY_PERIOD; |
| pHddTdlsCtx->threshold_config.discovery_tries_n = TDLS_MAX_DISCOVER_ATTEMPT; |
| pHddTdlsCtx->threshold_config.rx_timeout_t = TDLS_RX_IDLE_TIMEOUT; |
| pHddTdlsCtx->threshold_config.rssi_hysteresis = TDLS_RSSI_TRIGGER_HYSTERESIS; |
| |
| status = vos_timer_init(&pHddTdlsCtx->peerDiscoverTimer, |
| VOS_TIMER_TYPE_SW, |
| wlan_hdd_discover_peer_cb, |
| pHddTdlsCtx); |
| |
| status = vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer, |
| pHddTdlsCtx->threshold_config.discovery_period_t ); |
| |
| status = vos_timer_init(&pHddTdlsCtx->peerUpdateTimer, |
| VOS_TIMER_TYPE_SW, |
| wlan_hdd_update_peer_cb, |
| pHddTdlsCtx); |
| |
| status = vos_timer_start( &pHddTdlsCtx->peerUpdateTimer, |
| pHddTdlsCtx->threshold_config.tx_period_t ); |
| |
| return 0; |
| } |
| |
| void wlan_hdd_tdls_exit() |
| { |
| vos_timer_stop(&pHddTdlsCtx->peerDiscoverTimer); |
| vos_timer_destroy(&pHddTdlsCtx->peerDiscoverTimer); |
| vos_timer_stop(&pHddTdlsCtx->peerUpdateTimer); |
| vos_timer_destroy(&pHddTdlsCtx->peerUpdateTimer); |
| } |
| |
| int wlan_hdd_tdls_set_link_status(u8 *mac, int status) |
| { |
| hddTdlsPeer_t *curr_peer; |
| int i; |
| u8 key = 0; |
| |
| for (i = 0; i < 6; i++) |
| key ^= mac[i]; |
| |
| curr_peer = pHddTdlsCtx->peer_list[key]; |
| |
| if (NULL == curr_peer) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC!", __func__); |
| return -1; |
| } |
| |
| do { |
| if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer; |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC!", __func__); |
| return -1; |
| |
| found_peer: |
| |
| hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d link status to %d", |
| key, status); |
| |
| curr_peer->link_status = status; |
| |
| return status; |
| } |
| |
| int wlan_hdd_tdls_set_cap(u8 *mac, int cap) |
| { |
| hddTdlsPeer_t *curr_peer; |
| int i; |
| u8 key = 0; |
| |
| for (i = 0; i < 6; i++) |
| key ^= mac[i]; |
| |
| curr_peer = pHddTdlsCtx->peer_list[key]; |
| |
| if (NULL == curr_peer) { |
| curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| |
| if (NULL == curr_peer) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); |
| return -1; |
| } |
| vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t)); |
| |
| INIT_LIST_HEAD(&curr_peer->node); |
| memcpy(curr_peer->peerMac, mac, 6); |
| curr_peer->tdls_support = cap; |
| pHddTdlsCtx->peer_list[key] = curr_peer; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x", |
| key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
| curr_peer ); |
| return 0; |
| } |
| |
| do { |
| if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer; |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC %d: %x %x %x %x %x %x", |
| __func__, key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
| |
| return -1; |
| |
| found_peer: |
| |
| hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d support cap to %d", |
| key, cap); |
| |
| curr_peer->tdls_support = cap; |
| |
| return cap; |
| } |
| |
| int wlan_hdd_tdls_set_rssi(u8 *mac, tANI_S8 rxRssi) |
| { |
| hddTdlsPeer_t *curr_peer; |
| int i; |
| u8 key = 0; |
| |
| for (i = 0; i < 6; i++) |
| key ^= mac[i]; |
| |
| curr_peer = pHddTdlsCtx->peer_list[key]; |
| |
| if (NULL == curr_peer) { |
| curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| |
| if (NULL == curr_peer) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); |
| return -1; |
| } |
| vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t)); |
| |
| INIT_LIST_HEAD(&curr_peer->node); |
| memcpy(curr_peer->peerMac, mac, 6); |
| curr_peer->rssi = rxRssi; |
| pHddTdlsCtx->peer_list[key] = curr_peer; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x", |
| key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
| curr_peer ); |
| return 0; |
| } |
| |
| do { |
| if (!memcmp(mac, curr_peer->peerMac, 6)) goto found_peer; |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s no matching MAC %d: %x %x %x %x %x %x", |
| __func__, key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
| |
| return -1; |
| |
| found_peer: |
| |
| hddLog(VOS_TRACE_LEVEL_WARN, "tdls set peer %d rssi to %d", |
| key, rxRssi); |
| |
| curr_peer->rssi = rxRssi; |
| |
| return rxRssi; |
| } |
| |
| u8 wlan_hdd_tdls_extract_da(struct sk_buff *skb, u8 *mac) |
| { |
| int i; |
| u8 hash = 0; |
| |
| memcpy(mac, skb->data, 6); |
| for (i = 0; i < 6; i++) |
| hash ^= mac[i]; |
| |
| return hash; |
| } |
| |
| int wlan_hdd_tdls_add_peer_to_list(u8 key, u8 *mac) |
| { |
| hddTdlsPeer_t *new_peer, *curr_peer; |
| |
| curr_peer = pHddTdlsCtx->peer_list[key]; |
| |
| if (NULL == curr_peer) { |
| curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| |
| if (NULL == curr_peer) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); |
| return -1; |
| } |
| vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t)); |
| curr_peer->rssi = -120; |
| |
| INIT_LIST_HEAD(&curr_peer->node); |
| memcpy(curr_peer->peerMac, mac, 6); |
| |
| pHddTdlsCtx->peer_list[key] = curr_peer; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "new peer - key:%d, mac:%x %x %x %x %x %x, 0x%x", |
| key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
| curr_peer ); |
| return 0; |
| } |
| |
| do { |
| if (!memcmp(mac, curr_peer->peerMac, 6)) goto known_peer; |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| |
| new_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| if (NULL == new_peer) { |
| hddLog(VOS_TRACE_LEVEL_ERROR, "%s peer malloc failed!", __func__); |
| return -1; |
| } |
| vos_mem_zero(new_peer, sizeof(hddTdlsPeer_t)); |
| curr_peer->rssi = -120; |
| memcpy(new_peer->peerMac, mac, 6); |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "add peer - key:%d, mac:%x %x %x %x %x %x", |
| key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] ); |
| |
| list_add(&new_peer->node, &curr_peer->node); |
| curr_peer = new_peer; |
| |
| known_peer: |
| curr_peer->tx_pkt++; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "known peer - key:%d, mac:%x %x %x %x %x %x, tx:%d", |
| key, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], |
| curr_peer->tx_pkt ); |
| |
| return 0; |
| } |
| |
| int wlan_hdd_tdls_set_params(tdls_config_params_t *config) |
| { |
| vos_timer_stop( &pHddTdlsCtx->peerDiscoverTimer); |
| |
| vos_timer_stop( &pHddTdlsCtx->peerUpdateTimer); |
| |
| memcpy(&pHddTdlsCtx->threshold_config, config, sizeof(tdls_config_params_t)); |
| |
| VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, |
| "iw set tdls params: %d %d %d %d %d %d", |
| pHddTdlsCtx->threshold_config.tx_period_t, |
| pHddTdlsCtx->threshold_config.tx_packet_n, |
| pHddTdlsCtx->threshold_config.discovery_period_t, |
| pHddTdlsCtx->threshold_config.discovery_tries_n, |
| pHddTdlsCtx->threshold_config.rx_timeout_t, |
| pHddTdlsCtx->threshold_config.rssi_hysteresis); |
| |
| vos_timer_start( &pHddTdlsCtx->peerDiscoverTimer, |
| pHddTdlsCtx->threshold_config.discovery_period_t ); |
| |
| vos_timer_start( &pHddTdlsCtx->peerUpdateTimer, |
| pHddTdlsCtx->threshold_config.tx_period_t ); |
| return 0; |
| } |
| |
| int wlan_hdd_saveTdlsPeer(tCsrRoamInfo *pRoamInfo) |
| { |
| hddTdlsPeer_t *new_peer, *curr_peer; |
| int i; |
| u8 key = 0; |
| |
| for (i = 0; i < 6; i++) |
| key ^= pRoamInfo->peerMac[i]; |
| |
| curr_peer = pHddTdlsCtx->peer_list[key]; |
| |
| if (NULL == curr_peer) { |
| curr_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| |
| if (NULL == curr_peer) { |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, |
| "saveTdlsPeer: NOT saving staId %d", pRoamInfo->staId); |
| return -1; |
| } |
| vos_mem_zero(curr_peer, sizeof(hddTdlsPeer_t)); |
| |
| INIT_LIST_HEAD(&curr_peer->node); |
| memcpy(curr_peer->peerMac, pRoamInfo->peerMac, 6); |
| curr_peer->staId = pRoamInfo->staId; |
| pHddTdlsCtx->peer_list[key] = curr_peer; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "saveTdlsPeer: saved staId %d", pRoamInfo->staId); |
| return 0; |
| } |
| |
| do { |
| if (!memcmp(pRoamInfo->peerMac, curr_peer->peerMac, 6)) goto known_peer; |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| |
| new_peer = vos_mem_malloc(sizeof(hddTdlsPeer_t)); |
| if (NULL == new_peer) { |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, |
| "saveTdlsPeer: NOT saving staId %d", pRoamInfo->staId); |
| return -1; |
| } |
| vos_mem_zero(new_peer, sizeof(hddTdlsPeer_t)); |
| |
| list_add(&new_peer->node, &curr_peer->node); |
| curr_peer = new_peer; |
| |
| known_peer: |
| memcpy(curr_peer->peerMac, pRoamInfo->peerMac, 6); |
| curr_peer->staId = pRoamInfo->staId; |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "saveTdlsPeer: saved staId %d", pRoamInfo->staId); |
| |
| return 0; |
| } |
| |
| int wlan_hdd_findTdlsPeer(tSirMacAddr peerMac) |
| { |
| int i; |
| hddTdlsPeer_t *curr_peer; |
| |
| for (i = 0; i < 256; i++) { |
| curr_peer = pHddTdlsCtx->peer_list[i]; |
| if (NULL == curr_peer) continue; |
| |
| do { |
| if (!memcmp(peerMac, curr_peer->peerMac, 6)) { |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, |
| "findTdlsPeer: found staId %d", curr_peer->staId); |
| return curr_peer->staId; |
| } |
| |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| } |
| |
| VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, |
| "findTdlsPeer: staId NOT found"); |
| |
| return -1; |
| } |
| |
| void wlan_hdd_removeTdlsPeer(tCsrRoamInfo *pRoamInfo) |
| { |
| int i; |
| hddTdlsPeer_t *curr_peer; |
| |
| for (i = 0; i < 256; i++) { |
| |
| curr_peer = pHddTdlsCtx->peer_list[i]; |
| |
| if (NULL == curr_peer) continue; |
| |
| do { |
| if (curr_peer->staId == pRoamInfo->staId) goto found_peer; |
| |
| curr_peer = (hddTdlsPeer_t *)curr_peer->node.next; |
| } while (&curr_peer->node != curr_peer->node.next); |
| } |
| |
| if (i == 256) return; |
| |
| found_peer: |
| wlan_hdd_tdls_set_link_status(curr_peer->peerMac, 0); |
| wlan_hdd_tdls_set_cap(curr_peer->peerMac, 0); |
| wlan_hdd_tdls_set_rssi(curr_peer->peerMac, -120); |
| } |