qcacld-3.0: Avoid race condition in antenna switch operation
qcacld-2.0 to qcacld-3.0 propagation When the TDLS traffic flows continuously between the two peers and if the antenna switch command comes from the user, it creates a race condition and blocks the antenna switch operation. Add a new transition state in TDLS to avoid this race condition. Change-Id: I1c9b183c460e1401bd1ee2631489c57778ec665b CRs-Fixed: 971505
Dieser Commit ist enthalten in:

committet von
qcabuildsw

Ursprung
35cc2cf07c
Commit
ff89f748c1
@@ -1298,6 +1298,8 @@ struct hdd_context_s {
|
||||
bool enable_tdls_connection_tracker;
|
||||
uint8_t tdls_external_peer_count;
|
||||
bool tdls_nss_switch_in_progress;
|
||||
bool tdls_nss_teardown_complete;
|
||||
enum tdls_nss_transition_type tdls_nss_transition_mode;
|
||||
int32_t tdls_teardown_peers_cnt;
|
||||
struct tdls_set_state_info set_state_info;
|
||||
#endif
|
||||
|
@@ -144,6 +144,18 @@ enum tdls_spatial_streams {
|
||||
TDLS_NSS_2x2_MODE = 0xff,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tdls_nss_transition_type - TDLS NSS transition states
|
||||
* @TDLS_NSS_TRANSITION_UNKNOWN: default state
|
||||
* @TDLS_NSS_TRANSITION_2x2_to_1x1: transition from 2x2 to 1x1 stream
|
||||
* @TDLS_NSS_TRANSITION_1x1_to_2x2: transition from 1x1 to 2x2 stream
|
||||
*/
|
||||
enum tdls_nss_transition_type {
|
||||
TDLS_NSS_TRANSITION_UNKNOWN = 0,
|
||||
TDLS_NSS_TRANSITION_2x2_to_1x1,
|
||||
TDLS_NSS_TRANSITION_1x1_to_2x2,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum tTDLSCapType - tdls capability type
|
||||
*
|
||||
|
@@ -6691,6 +6691,17 @@ static int drv_cmd_set_antenna_mode(hdd_adapter_t *adapter,
|
||||
hdd_ctx->current_antenna_mode);
|
||||
ret = 0;
|
||||
exit:
|
||||
#ifdef FEATURE_WLAN_TDLS
|
||||
/* Reset tdls NSS flags */
|
||||
if (hdd_ctx->tdls_nss_switch_in_progress &&
|
||||
hdd_ctx->tdls_nss_teardown_complete) {
|
||||
hdd_ctx->tdls_nss_switch_in_progress = false;
|
||||
hdd_ctx->tdls_nss_teardown_complete = false;
|
||||
}
|
||||
hdd_info("tdls_nss_switch_in_progress: %d tdls_nss_teardown_complete: %d",
|
||||
hdd_ctx->tdls_nss_switch_in_progress,
|
||||
hdd_ctx->tdls_nss_teardown_complete);
|
||||
#endif
|
||||
hdd_info("Set antenna status: %d current mode: %d",
|
||||
ret, hdd_ctx->current_antenna_mode);
|
||||
return ret;
|
||||
|
@@ -654,6 +654,8 @@ void hdd_tdls_context_init(hdd_context_t *hdd_ctx)
|
||||
hdd_ctx->tdls_external_peer_count = 0;
|
||||
hdd_ctx->set_state_info.set_state_cnt = 0;
|
||||
hdd_ctx->set_state_info.vdev_id = 0;
|
||||
hdd_ctx->tdls_nss_teardown_complete = false;
|
||||
hdd_ctx->tdls_nss_transition_mode = TDLS_NSS_TRANSITION_UNKNOWN;
|
||||
|
||||
/* This flag will set be true, only when device operates in
|
||||
* standalone STA mode
|
||||
@@ -4082,8 +4084,24 @@ static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
|
||||
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;
|
||||
if (pHddCtx->tdls_teardown_peers_cnt == 0) {
|
||||
if (pHddCtx->tdls_nss_transition_mode ==
|
||||
TDLS_NSS_TRANSITION_1x1_to_2x2) {
|
||||
/* TDLS NSS switch is fully completed, so
|
||||
* reset the flags.
|
||||
*/
|
||||
hdd_info("TDLS NSS switch is fully completed");
|
||||
pHddCtx->tdls_nss_switch_in_progress = false;
|
||||
pHddCtx->tdls_nss_teardown_complete = false;
|
||||
} else {
|
||||
/* TDLS NSS switch is not yet completed, but
|
||||
* tdls teardown is completed for all the
|
||||
* peers.
|
||||
*/
|
||||
hdd_info("TDLS teardown is completed and NSS switch still in progress");
|
||||
pHddCtx->tdls_nss_teardown_complete = true;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&pHddCtx->tdls_lock);
|
||||
}
|
||||
|
||||
@@ -5829,11 +5847,16 @@ static int wlan_hdd_tdls_teardown_links(hdd_context_t *hddctx,
|
||||
hdd_info("TDLS peers to be torn down = %d",
|
||||
hddctx->tdls_teardown_peers_cnt);
|
||||
/* Antenna switch 2x2 to 1x1 */
|
||||
if (mode == HDD_ANTENNA_MODE_1X1)
|
||||
if (mode == HDD_ANTENNA_MODE_1X1) {
|
||||
hddctx->tdls_nss_transition_mode =
|
||||
TDLS_NSS_TRANSITION_2x2_to_1x1;
|
||||
ret = -EAGAIN;
|
||||
else
|
||||
} else {
|
||||
/* Antenna switch 1x1 to 2x2 */
|
||||
hddctx->tdls_nss_transition_mode =
|
||||
TDLS_NSS_TRANSITION_1x1_to_2x2;
|
||||
ret = 0;
|
||||
}
|
||||
hdd_info("TDLS teardown for antenna switch operation starts");
|
||||
}
|
||||
mutex_unlock(&hddctx->tdls_lock);
|
||||
@@ -5858,8 +5881,12 @@ int wlan_hdd_tdls_antenna_switch(hdd_context_t *hdd_ctx,
|
||||
|
||||
/* Check whether TDLS antenna switch is in progress */
|
||||
if (hdd_ctx->tdls_nss_switch_in_progress) {
|
||||
hdd_err("TDLS antenna switch is in progress");
|
||||
return -EAGAIN;
|
||||
if (hdd_ctx->tdls_nss_teardown_complete == false) {
|
||||
hdd_err("TDLS antenna switch is in progress");
|
||||
return -EAGAIN;
|
||||
} else {
|
||||
goto tdls_ant_sw_done;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether TDLS is connected or not */
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren