diff options
| author | Archana Ramachandran <archanar@codeaurora.org> | 2016-04-20 16:57:35 -0700 |
|---|---|---|
| committer | Nandini Suresh <snandini@codeaurora.org> | 2016-06-29 18:41:22 -0700 |
| commit | d5d2e926c87d95fdbbe169667c7693cde70eaef3 (patch) | |
| tree | 05982dd6318c7511745907153cf2e9c08ee932b9 | |
| parent | 99bac319a8e7dd2ddf76a2d8dcaa8950b5d4e8e2 (diff) | |
qcacld-3.0: Dynamic antenna switch in TDLS operation
qcacld-2.0 to qcacld-3.0 propagation
Add dynamic antenna mode change capability for TDLS
operation.
CRs-Fixed: 951596
Change-Id: Ie0b141fbebe0bfa8a173503fc0ec375095240237
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_tdls.h | 9 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_ioctl.c | 9 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_tdls.c | 117 |
4 files changed, 137 insertions, 0 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 0bbc37a7fbd1..072e8b6f4714 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1259,6 +1259,8 @@ struct hdd_context_s { int32_t tdls_fw_off_chan_mode; bool enable_tdls_connection_tracker; uint8_t tdls_external_peer_count; + bool tdls_nss_switch_in_progress; + int32_t tdls_teardown_peers_cnt; #endif void *hdd_ipa; diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 7b770ac9e37a..4ad93bc93e2b 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -669,6 +669,9 @@ void wlan_hdd_tdls_update_rx_pkt_cnt(hdd_adapter_t *adapter, int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val); void hdd_tdls_context_init(hdd_context_t *hdd_ctx); void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx); +int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter); + #else static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, hdd_context_t *hddctx) @@ -691,6 +694,12 @@ static inline void wlan_hdd_tdls_update_rx_pkt_cnt(hdd_adapter_t *adapter, } static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { } static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { } + +static inline int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter) +{ + return 0; +} #endif /* End of FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 0d6320ef665b..773951b3952d 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -6611,6 +6611,15 @@ static int drv_cmd_set_antenna_mode(hdd_adapter_t *adapter, goto exit; } + /* Check TDLS status and update antenna mode */ + if ((QDF_STA_MODE == adapter->device_mode) && + cds_is_sta_active_connection_exists() && + (hdd_ctx->connected_peer_count > 0)) { + ret = wlan_hdd_tdls_antenna_switch(hdd_ctx, adapter); + if (0 != ret) + goto exit; + } + params.set_antenna_mode_resp = (void *)wlan_hdd_soc_set_antenna_mode_cb; hdd_info("Set antenna mode rx chains: %d tx chains: %d", diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index e1bb1e3dd9a1..7c9cfce9f168 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -743,6 +743,8 @@ int wlan_hdd_tdls_init(hdd_adapter_t *pAdapter) /* initialize TDLS global context */ pHddCtx->connected_peer_count = 0; + pHddCtx->tdls_nss_switch_in_progress = false; + pHddCtx->tdls_teardown_peers_cnt = 0; sme_set_tdls_power_save_prohibited(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId, 0); @@ -4068,6 +4070,17 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, return -EINVAL; } + if (SIR_MAC_TDLS_TEARDOWN == action_code && + pHddCtx->tdls_nss_switch_in_progress) { + mutex_lock(&pHddCtx->tdls_lock); + if (pHddCtx->tdls_teardown_peers_cnt != 0) + pHddCtx->tdls_teardown_peers_cnt--; + if (pHddCtx->tdls_teardown_peers_cnt == 0) + pHddCtx->tdls_nss_switch_in_progress = false; + mutex_unlock(&pHddCtx->tdls_lock); + } + + if ((SIR_MAC_TDLS_DIS_REQ == action_code) || (SIR_MAC_TDLS_DIS_RSP == action_code)) { /* for DIS_REQ/DIS_RSP, supplicant does not consider the return @@ -5744,3 +5757,107 @@ int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val) return 0; } } + +/** + * wlan_hdd_tdls_teardown_links() - teardown tdls links + * @hddCtx : pointer to hdd context + * + * Return: 0 if success else non zero + */ +static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx) +{ + uint16_t connected_tdls_peers = 0; + uint8_t staidx; + hddTdlsPeer_t *curr_peer; + hdd_adapter_t *adapter; + + if (eTDLS_SUPPORT_NOT_ENABLED == hddctx->tdls_mode) { + hdd_log(LOG1, "TDLS mode is disabled OR not enabled in FW"); + return 0; + } + + adapter = hdd_get_adapter(hddctx, QDF_STA_MODE); + + if (adapter == NULL) { + hdd_log(LOGE, "Station Adapter Not Found"); + return 0; + } + + connected_tdls_peers = wlan_hdd_tdls_connected_peers(adapter); + + if (!connected_tdls_peers) + return 0; + + for (staidx = 0; staidx < hddctx->max_num_tdls_sta; + staidx++) { + if (!hddctx->tdlsConnInfo[staidx].staId) + continue; + + curr_peer = wlan_hdd_tdls_find_all_peer(hddctx, + hddctx->tdlsConnInfo[staidx].peerMac.bytes); + + if (!curr_peer) + continue; + + hdd_log(LOG1, "indicate TDLS teardown (staId %d)", + curr_peer->staId); + + wlan_hdd_tdls_indicate_teardown( + curr_peer->pHddTdlsCtx->pAdapter, + curr_peer, + eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + mutex_lock(&hddctx->tdls_lock); + hddctx->tdls_teardown_peers_cnt++; + mutex_unlock(&hddctx->tdls_lock); + } + mutex_lock(&hddctx->tdls_lock); + if (hddctx->tdls_teardown_peers_cnt >= 1) + hddctx->tdls_nss_switch_in_progress = true; + hdd_log(LOGE, "TDLS peers to be torn down = %d", + hddctx->tdls_teardown_peers_cnt); + mutex_unlock(&hddctx->tdls_lock); + hdd_log(LOGE, "TDLS teardown for antenna switch operation starts"); + return -EAGAIN; +} + +/** + * wlan_hdd_tdls_antenna_switch() - Dynamic TDLS antenna switch 1x1 <-> 2x2 + * antenna mode in standalone station + * @hdd_ctx: Pointer to hdd contex + * @adapter: Pointer to hdd adapter + * + * Return: 0 if success else non zero + */ +int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx, + hdd_adapter_t *adapter) +{ + uint8_t tdls_peer_cnt; + hdd_station_ctx_t *sta_ctx = + WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + /* Check whether TDLS antenna switch is in progress */ + if (hdd_ctx->tdls_nss_switch_in_progress) { + hdd_log(LOGE, "TDLS antenna switch is in progress"); + return -EAGAIN; + } + + /* Check whether TDLS is connected or not */ + mutex_lock(&hdd_ctx->tdls_lock); + tdls_peer_cnt = hdd_ctx->connected_peer_count; + mutex_unlock(&hdd_ctx->tdls_lock); + if (tdls_peer_cnt <= 0) + goto tdls_ant_sw_done; + + /* Check the current operating band */ + if (!IS_5G_CH(sta_ctx->conn_info.operationChannel)) { + hdd_log(LOGE, "TDLS is in 2.4G, Ant switch not needed"); + return 0; + } + + /* teardown all the tdls connections */ + return wlan_hdd_tdls_teardown_links(hdd_ctx); + +tdls_ant_sw_done: + hdd_log(LOGE, "No TDLS connection established"); + return 0; +} |
