diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 02edafa2bef2..afb8fe9bcbf3 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2115,7 +2115,8 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, tCsrRoamInfo *roam_info, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, u16 status, gfp_t gfp, - bool connect_timeout); + bool connect_timeout, + tSirResultCodes timeout_reason); #ifdef WLAN_FEATURE_FASTPATH void hdd_enable_fastpath(struct hdd_config *hdd_cfg, diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 41d903e0f3e6..9302e8468a42 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -2362,6 +2362,7 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, int ft_carrier_on = false; bool hddDisconInProgress = false; unsigned long rc; + tSirResultCodes timeout_reason = 0; if (!pHddCtx) { hdd_err("HDD context is NULL"); @@ -2683,16 +2684,17 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, hdd_info("ft_carrier_on is %d, sending connect indication", ft_carrier_on); hdd_connect_result(dev, - pRoamInfo-> - bssid.bytes, - pRoamInfo, - pFTAssocReq, - assocReqlen, - pFTAssocRsp, - assocRsplen, - WLAN_STATUS_SUCCESS, - GFP_KERNEL, - false); + pRoamInfo-> + bssid.bytes, + pRoamInfo, + pFTAssocReq, + assocReqlen, + pFTAssocRsp, + assocRsplen, + WLAN_STATUS_SUCCESS, + GFP_KERNEL, + false, + pRoamInfo->statusCode); } } else { /* @@ -2727,16 +2729,17 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, /* inform connect result to nl80211 */ hdd_connect_result(dev, - pRoamInfo-> - bssid.bytes, - pRoamInfo, - reqRsnIe, - reqRsnLength, - rspRsnIe, - rspRsnLength, - WLAN_STATUS_SUCCESS, - GFP_KERNEL, - false); + pRoamInfo-> + bssid.bytes, + pRoamInfo, + reqRsnIe, + reqRsnLength, + rspRsnIe, + rspRsnLength, + WLAN_STATUS_SUCCESS, + GFP_KERNEL, + false, + pRoamInfo->statusCode); } } } @@ -2907,14 +2910,16 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, NULL, NULL, 0, NULL, 0, WLAN_STATUS_ASSOC_DENIED_UNSPEC, GFP_KERNEL, - connect_timeout); + connect_timeout, + pRoamInfo->statusCode); else hdd_connect_result(dev, pWextState->req_bssId.bytes, NULL, NULL, 0, NULL, 0, WLAN_STATUS_ASSOC_DENIED_UNSPEC, GFP_KERNEL, - connect_timeout); + connect_timeout, + timeout_reason); } else { if (pRoamInfo) hdd_connect_result(dev, @@ -2924,14 +2929,16 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, pRoamInfo->reasonCode : WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL, - connect_timeout); + connect_timeout, + pRoamInfo->statusCode); else hdd_connect_result(dev, pWextState->req_bssId.bytes, NULL, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL, - connect_timeout); + connect_timeout, + timeout_reason); } hdd_clear_roam_profile_ie(pAdapter); } else if ((eCSR_ROAM_CANCELLED == roamStatus @@ -2941,7 +2948,8 @@ static QDF_STATUS hdd_association_completion_handler(hdd_adapter_t *pAdapter, NULL, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL, - connect_timeout); + connect_timeout, + timeout_reason); } /* diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 63721ea80a90..7335d101d5b8 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -112,6 +112,7 @@ #include #include #include "wlan_pmo_ucfg_api.h" +#include "sir_api.h" #ifdef MODULE #define WLAN_MODULE_NAME module_name(THIS_MODULE) @@ -3962,6 +3963,101 @@ struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy, #endif #if defined CFG80211_CONNECT_BSS +#if defined CFG80211_CONNECT_TIMEOUT_REASON_CODE || \ + (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)) +/** + * hdd_convert_timeout_reason() - Convert to kernel specific enum + * @timeout_reason: reason for connect timeout + * + * This function is used to convert host timeout + * reason enum to kernel specific enum. + * + * Return: nl timeout enum + */ +static enum nl80211_timeout_reason hdd_convert_timeout_reason( + tSirResultCodes timeout_reason) +{ + switch (timeout_reason) { + case eSIR_SME_JOIN_TIMEOUT_RESULT_CODE: + return NL80211_TIMEOUT_SCAN; + case eSIR_SME_AUTH_TIMEOUT_RESULT_CODE: + return NL80211_TIMEOUT_AUTH; + case eSIR_SME_ASSOC_TIMEOUT_RESULT_CODE: + return NL80211_TIMEOUT_ASSOC; + default: + return NL80211_TIMEOUT_UNSPECIFIED; + } +} + +/** + * hdd_cfg80211_connect_timeout() - API to send connection timeout reason + * @dev: network device + * @bssid: bssid to which we want to associate + * @timeout_reason: reason for connect timeout + * + * This API is used to send connection timeout reason to supplicant + * + * Return: void + */ +static void hdd_cfg80211_connect_timeout(struct net_device *dev, + const u8 *bssid, + tSirResultCodes timeout_reason) +{ + enum nl80211_timeout_reason nl_timeout_reason; + nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason); + + cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL, + nl_timeout_reason); +} + +/** + * __hdd_connect_bss() - API to send connection status to supplicant + * @dev: network device + * @bssid: bssid to which we want to associate + * @req_ie: Request Information Element + * @req_ie_len: len of the req IE + * @resp_ie: Response IE + * @resp_ie_len: len of ht response IE + * @status: status + * @gfp: Kernel Flag + * @timeout_reason: reason for connect timeout + * + * Return: void + */ +static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid, + struct cfg80211_bss *bss, const u8 *req_ie, + size_t req_ie_len, const u8 *resp_ie, + size_t resp_ie_len, int status, gfp_t gfp, + tSirResultCodes timeout_reason) +{ + enum nl80211_timeout_reason nl_timeout_reason; + nl_timeout_reason = hdd_convert_timeout_reason(timeout_reason); + + cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len, + resp_ie, resp_ie_len, status, gfp, + nl_timeout_reason); +} +#else +#if defined CFG80211_CONNECT_TIMEOUT +static void hdd_cfg80211_connect_timeout(struct net_device *dev, + const u8 *bssid, + tSirResultCodes timeout_reason) +{ + cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL); +} +#endif + +static void __hdd_connect_bss(struct net_device *dev, const u8 *bssid, + struct cfg80211_bss *bss, const u8 *req_ie, + size_t req_ie_len, const u8 *resp_ie, + size_t resp_ie_len, int status, gfp_t gfp, + tSirResultCodes timeout_reason) +{ + cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len, + resp_ie, resp_ie_len, status, gfp); +} +#endif + /** * hdd_connect_bss() - API to send connection status to supplicant * @dev: network device @@ -3973,6 +4069,7 @@ struct cfg80211_bss *hdd_cfg80211_get_bss(struct wiphy *wiphy, * @status: status * @gfp: Kernel Flag * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp + * @timeout_reason: reason for connect timeout * * The API is a wrapper to send connection status to supplicant * @@ -3983,23 +4080,25 @@ static void hdd_connect_bss(struct net_device *dev, const u8 *bssid, struct cfg80211_bss *bss, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, int status, gfp_t gfp, - bool connect_timeout) + bool connect_timeout, + tSirResultCodes timeout_reason) { if (connect_timeout) - cfg80211_connect_timeout(dev, bssid, NULL, 0, GFP_KERNEL); + hdd_cfg80211_connect_timeout(dev, bssid, timeout_reason); else - cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len, - resp_ie, resp_ie_len, status, gfp); + __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, + resp_ie_len, status, gfp, timeout_reason); } #else static void hdd_connect_bss(struct net_device *dev, const u8 *bssid, struct cfg80211_bss *bss, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, int status, gfp_t gfp, - bool connect_timeout) + bool connect_timeout, + tSirResultCodes timeout_reason) { - cfg80211_connect_bss(dev, bssid, bss, req_ie, req_ie_len, - resp_ie, resp_ie_len, status, gfp); + __hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, + resp_ie_len, status, gfp, timeout_reason); } #endif @@ -4015,6 +4114,7 @@ static void hdd_connect_bss(struct net_device *dev, const u8 *bssid, * @status: status * @gfp: Kernel Flag * @connect_timeout: If timed out waiting for Auth/Assoc/Probe resp + * @timeout_reason: reason for connect timeout * * The API is a wrapper to send connection status to supplicant * and allow runtime suspend @@ -4025,7 +4125,8 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, tCsrRoamInfo *roam_info, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, u16 status, gfp_t gfp, - bool connect_timeout) + bool connect_timeout, + tSirResultCodes timeout_reason) { hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev); struct cfg80211_bss *bss = NULL; @@ -4050,7 +4151,7 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, hdd_connect_bss(dev, bssid, bss, req_ie, req_ie_len, resp_ie, resp_ie_len, - status, gfp, connect_timeout); + status, gfp, connect_timeout, timeout_reason); qdf_runtime_pm_allow_suspend(padapter->connect_rpm_ctx.connect); } @@ -4059,7 +4160,8 @@ void hdd_connect_result(struct net_device *dev, const u8 *bssid, tCsrRoamInfo *roam_info, const u8 *req_ie, size_t req_ie_len, const u8 *resp_ie, size_t resp_ie_len, u16 status, gfp_t gfp, - bool connect_timeout) + bool connect_timeout, + tSirResultCodes timeout_reason) { hdd_adapter_t *padapter = (hdd_adapter_t *) netdev_priv(dev); @@ -4129,9 +4231,10 @@ QDF_STATUS hdd_start_all_adapters(hdd_context_t *hdd_ctx) * process of connecting */ hdd_connect_result(adapter->dev, NULL, NULL, - NULL, 0, NULL, 0, - WLAN_STATUS_ASSOC_DENIED_UNSPEC, - GFP_KERNEL, false); + NULL, 0, NULL, 0, + WLAN_STATUS_ASSOC_DENIED_UNSPEC, + GFP_KERNEL, false, + 0); } hdd_register_tx_flow_control(adapter,