qcacld-3.0: Reconnect to same BSS once again ifdd assoc timeout

Add INI - gActionOUIReconnAssocTimeout to configure driver
to do:
1. Driver will not send deauth to the AP after association timeout.
2. Reconnect to same BSS again if the last association failure
is association response timeout.
Default="00E04C 00 01"

The change fixes IOT issue with certain AP which doesn't
response first association request frame sometime. But the AP
would response second association request.

Change-Id: I9f7b8d14aaaaa97f08856c8b62e49b145db3ac91
CRs-Fixed: 2653877
This commit is contained in:
Liangwei Dong
2020-04-13 10:43:58 +08:00
committed by nshrivas
parent 83b3d290ea
commit eb4d039e1f
8 changed files with 169 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
@@ -90,6 +90,10 @@
* @ACTION_OUI_DISABLE_AGGRESSIVE_TX: disable aggressive TX in firmware
* @ACTION_OUI_FORCE_MAX_NSS: Force Max NSS connection with few IOT APs
* @ACTION_OUI_DISABLE_AGGRESSIVE_EDCA: disable aggressive EDCA with the ap
* @ACTION_OUI_HOST_ONLY: host only action id start - placeholder.
* New Firmware related "ACTION" needs to be added before this placeholder.
* @ACTION_OUI_HOST_RECONN: reconnect to the same BSSID when wait for
* association response timeout from AP
* @ACTION_OUI_MAXIMUM_ID: maximum number of action oui types
*/
enum action_oui_id {
@@ -102,6 +106,8 @@ enum action_oui_id {
ACTION_OUI_DISABLE_AGGRESSIVE_TX = 6,
ACTION_OUI_FORCE_MAX_NSS = 7,
ACTION_OUI_DISABLE_AGGRESSIVE_EDCA = 8,
ACTION_OUI_HOST_ONLY,
ACTION_OUI_HOST_RECONN = ACTION_OUI_HOST_ONLY,
ACTION_OUI_MAXIMUM_ID
};

View File

@@ -153,6 +153,8 @@ QDF_STATUS ucfg_action_oui_send(struct wlan_objmgr_psoc *psoc)
}
for (id = 0; id < ACTION_OUI_MAXIMUM_ID; id++) {
if (id >= ACTION_OUI_HOST_ONLY)
continue;
status = action_oui_send(psoc_priv, id);
if (!QDF_IS_STATUS_SUCCESS(status))
action_oui_err("Failed to send: %u", id);

View File

@@ -137,6 +137,7 @@ struct wlan_mlme_roam {
* @connection_fail: flag to indicate connection failed
* @cac_required_for_new_channel: if CAC is required for new channel
* @follow_ap_edca: if true, it is forced to follow the AP's edca.
* @reconn_after_assoc_timeout: reconnect to the same AP if association timeout
* @assoc_type: vdev associate/reassociate type
* @dynamic_cfg: current configuration of nss, chains for vdev.
* @ini_cfg: Max configuration of nss, chains supported for vdev.
@@ -154,6 +155,7 @@ struct mlme_legacy_priv {
bool connection_fail;
bool cac_required_for_new_channel;
bool follow_ap_edca;
bool reconn_after_assoc_timeout;
enum vdev_assoc_type assoc_type;
struct wlan_mlme_nss_chains dynamic_cfg;
struct wlan_mlme_nss_chains ini_cfg;
@@ -339,6 +341,29 @@ void mlme_set_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev, bool flag);
*/
bool mlme_get_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev);
/**
* mlme_set_reconn_after_assoc_timeout_flag() - Set reconn after assoc timeout
* flag
* @psoc: soc object
* @vdev_id: vdev id
* @flag: enable or disable reconnect
*
* Return: void
*/
void mlme_set_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, bool flag);
/**
* mlme_get_reconn_after_assoc_timeout_flag() - Get reconn after assoc timeout
* flag
* @psoc: soc object
* @vdev_id: vdev id
*
* Return: true for enabling reconnect, otherwise false
*/
bool mlme_get_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
/**
* mlme_get_peer_disconnect_ies() - Get diconnect IEs from vdev object
* @vdev: vdev pointer

View File

@@ -2582,6 +2582,57 @@ bool mlme_get_follow_ap_edca_flag(struct wlan_objmgr_vdev *vdev)
return mlme_priv->follow_ap_edca;
}
void mlme_set_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id, bool flag)
{
struct wlan_objmgr_vdev *vdev;
struct mlme_legacy_priv *mlme_priv;
if (!psoc)
return;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_LEGACY_MAC_ID);
if (!vdev)
return;
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
if (!mlme_priv) {
mlme_legacy_err("vdev legacy private object is NULL");
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
return;
}
mlme_priv->reconn_after_assoc_timeout = flag;
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
}
bool mlme_get_reconn_after_assoc_timeout_flag(struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id)
{
struct wlan_objmgr_vdev *vdev;
struct mlme_legacy_priv *mlme_priv;
bool reconn_after_assoc_timeout;
if (!psoc)
return false;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id,
WLAN_LEGACY_MAC_ID);
if (!vdev)
return false;
mlme_priv = wlan_vdev_mlme_get_ext_hdl(vdev);
if (!mlme_priv) {
mlme_legacy_err("vdev legacy private object is NULL");
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
return false;
}
reconn_after_assoc_timeout = mlme_priv->reconn_after_assoc_timeout;
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_MAC_ID);
return reconn_after_assoc_timeout;
}
void mlme_set_peer_pmf_status(struct wlan_objmgr_peer *peer,
bool is_pmf_enabled)
{

View File

@@ -1224,6 +1224,39 @@ struct dhcp_server {
"", \
"Used to specify action OUIs to control edca configuration")
/*
* <ini>
* gActionOUIReconnAssocTimeout - Used to specify action OUIs to
* reconnect to same BSSID when wait for association response timeout
*
* This ini is used to specify AP OUIs. Some of AP doesn't response our
* first association request, but it would response our second association
* request. Add such OUI configuration INI to apply reconnect logic when
* association timeout happends with such AP.
* For default:
* gActionOUIReconnAssocTimeout=00E04C 00 01
* Explain: 00E04C: OUI
* 00: data length is 0
* 01: info mask, only OUI present in Info mask
* Note: User should strictly add new action OUIs at the end of this
* default value.
* Refer to gEnableActionOUI for more detail about the format.
*
* Related: gEnableActionOUI
*
* Supported Feature: Action OUIs
*
* Usage: External
*
* </ini>
*/
#define CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT CFG_INI_STRING( \
"gActionOUIReconnAssocTimeout", \
0, \
ACTION_OUI_MAX_STR_LEN, \
"00E04C 00 01", \
"Used to specify action OUIs to reconnect when assoc timeout")
/* End of action oui inis */
#ifdef ENABLE_MTRACE_LOG
@@ -1552,6 +1585,7 @@ enum host_log_level {
CFG(CFG_ACTION_OUI_FORCE_MAX_NSS) \
CFG(CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA) \
CFG(CFG_ACTION_OUI_SWITCH_TO_11N_MODE) \
CFG(CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT) \
CFG(CFG_ADVERTISE_CONCURRENT_OPERATION) \
CFG(CFG_BUG_ON_REINIT_FAILURE) \
CFG(CFG_DBS_SCAN_SELECTION) \

View File

@@ -10843,6 +10843,10 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
cfg_get(psoc,
CFG_ACTION_OUI_DISABLE_AGGRESSIVE_EDCA),
ACTION_OUI_MAX_STR_LEN);
qdf_str_lcopy(config->action_oui_str[ACTION_OUI_HOST_RECONN],
cfg_get(psoc, CFG_ACTION_OUI_RECONN_ASSOCTIMEOUT),
ACTION_OUI_MAX_STR_LEN);
config->is_unit_test_framework_enabled =
cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);

View File

@@ -1841,13 +1841,22 @@ void lim_process_assoc_failure_timeout(struct mac_context *mac_ctx,
* when device has missed the assoc resp sent by peer.
* By sending deauth try to clear the session created on peer device.
*/
pe_debug("Sessionid: %d try sending deauth on channel freq %d to BSSID: "
QDF_MAC_ADDR_STR, session->peSessionId,
if (msg_type == LIM_ASSOC &&
mlme_get_reconn_after_assoc_timeout_flag(mac_ctx->psoc,
session->vdev_id)) {
pe_debug("vdev: %d skip sending deauth on channel freq %d to BSSID: "
QDF_MAC_ADDR_STR, session->vdev_id,
session->curr_op_freq,
QDF_MAC_ADDR_ARRAY(session->bssId));
lim_send_deauth_mgmt_frame(mac_ctx, eSIR_MAC_UNSPEC_FAILURE_REASON,
} else {
pe_debug("vdev: %d try sending deauth on channel freq %d to BSSID: "
QDF_MAC_ADDR_STR, session->vdev_id,
session->curr_op_freq,
QDF_MAC_ADDR_ARRAY(session->bssId));
lim_send_deauth_mgmt_frame(mac_ctx,
eSIR_MAC_UNSPEC_FAILURE_REASON,
session->bssId, session, false);
}
if ((LIM_IS_AP_ROLE(session)) ||
((session->limMlmState != eLIM_MLM_WT_ASSOC_RSP_STATE) &&
(session->limMlmState != eLIM_MLM_WT_REASSOC_RSP_STATE) &&

View File

@@ -9481,6 +9481,7 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
uint32_t len = 0, roamId = 0, reason_code = 0;
bool is_dis_pending;
bool use_same_bss = false;
bool retry_same_bss = false;
if (!pSmeJoinRsp) {
sme_err("Sme Join Response is NULL");
@@ -9573,7 +9574,6 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
* AP.
*/
if (reason_code == eSIR_MAC_INVALID_PMKID) {
struct tag_csrscan_result *scan_result;
pmksa = qdf_mem_malloc(sizeof(*pmksa));
if (!pmksa)
return;
@@ -9586,18 +9586,28 @@ static void csr_roam_join_rsp_processor(struct mac_context *mac,
sme_roam_del_pmkid_from_cache(mac_handle, session_ptr->vdev_id,
pmksa, false);
qdf_mem_free(pmksa);
if (pCommand && pCommand->u.roamCmd.pRoamBssEntry) {
retry_same_bss = true;
}
if (pSmeJoinRsp->messageType == eWNI_SME_JOIN_RSP &&
pSmeJoinRsp->status_code == eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE &&
mlme_get_reconn_after_assoc_timeout_flag(mac->psoc,
pSmeJoinRsp->vdev_id))
retry_same_bss = true;
if (retry_same_bss && pCommand && pCommand->u.roamCmd.pRoamBssEntry) {
struct tag_csrscan_result *scan_result;
scan_result =
GET_BASE_ADDR(pCommand->u.roamCmd.pRoamBssEntry,
struct tag_csrscan_result, Link);
/* Retry with same BSSID without PMKID */
if (!scan_result->retry_count) {
sme_info("Retry once again with same BSSID without PMKID");
sme_info("Retry once with same BSSID, status %d reason %d",
pSmeJoinRsp->status_code, reason_code);
scan_result->retry_count = 1;
use_same_bss = true;
}
}
}
/* If Join fails while Handoff is in progress, indicate
* disassociated event to supplicant to reconnect
@@ -15426,6 +15436,7 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
uint8_t ap_nss;
struct wlan_objmgr_vdev *vdev;
bool follow_ap_edca;
bool reconn_after_assoc_timeout = false;
if (!pSession) {
sme_err("session %d not found", sessionId);
@@ -15607,6 +15618,14 @@ QDF_STATUS csr_send_join_req_msg(struct mac_context *mac, uint32_t sessionId,
&vendor_ap_search_attr,
ACTION_OUI_DISABLE_AGGRESSIVE_EDCA);
if (messageType == eWNI_SME_JOIN_REQ &&
ucfg_action_oui_search(mac->psoc, &vendor_ap_search_attr,
ACTION_OUI_HOST_RECONN))
reconn_after_assoc_timeout = true;
mlme_set_reconn_after_assoc_timeout_flag(
mac->psoc, sessionId,
reconn_after_assoc_timeout);
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc,
sessionId,
WLAN_LEGACY_MAC_ID);