From 0dc1a6e77a7a4ddd678116a02c87dfdca2755bb0 Mon Sep 17 00:00:00 2001 From: Ganesh Kondabattini Date: Sat, 29 Jul 2017 12:59:19 +0530 Subject: [PATCH] qcacld-3.0: Handle error cases while registering frames If registration of callback 'hdd_send_action_cnf_cb' fails with PE due to some error case, then PE is not going give the ack confirmation for action frames which can lead to in p2p connection failure. CRs-Fixed: 2075708 Change-Id: Ia7b670f186975f5139e37e79230de56bc8ab868b --- core/hdd/src/wlan_hdd_cfg80211.c | 78 ++++++++++++++++++++++++++++---- core/hdd/src/wlan_hdd_cfg80211.h | 13 +++++- core/hdd/src/wlan_hdd_main.c | 7 ++- 3 files changed, 86 insertions(+), 12 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 8eaa0040ee85..216f64cb3d1c 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -11634,19 +11634,30 @@ void wlan_hdd_cfg80211_update_wiphy_caps(struct wiphy *wiphy) /* This function registers for all frame which supplicant is interested in */ #if defined(CONVERGED_P2P_ENABLE) || defined(CONVERGED_TDLS_ENABLE) -void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter) +int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter) { tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); /* Register for all P2P action, public action etc frames */ uint16_t type = (SIR_MAC_MGMT_FRAME << 2) | (SIR_MAC_MGMT_ACTION << 4); + QDF_STATUS status; ENTER(); /* Register frame indication call back */ - sme_register_mgmt_frame_ind_callback(hHal, hdd_indicate_mgmt_frame); + status = sme_register_mgmt_frame_ind_callback(hHal, + hdd_indicate_mgmt_frame); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register hdd_indicate_mgmt_frame"); + goto ret_status; + } /* Register for p2p ack indication */ - sme_register_p2p_ack_ind_callback(hHal, hdd_send_action_cnf_cb); + status = sme_register_p2p_ack_ind_callback(hHal, + hdd_send_action_cnf_cb); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register p2p_ack_ind_callback"); + goto ret_status; + } /* Right now we are registering these frame when driver is getting * initialized. Once we will move to 2.6.37 kernel, in which we have @@ -11654,37 +11665,84 @@ void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter) */ /* GAS Initial Request */ - sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, (uint8_t *) GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register GAS_INITIAL_REQ"); + goto ret_status; + } /* GAS Initial Response */ - sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, (uint8_t *) GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register GAS_INITIAL_RSP"); + goto dereg_gas_initial_req; + } /* GAS Comeback Request */ - sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, (uint8_t *) GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register GAS_COMEBACK_REQ"); + goto dereg_gas_initial_rsp; + } /* GAS Comeback Response */ - sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, (uint8_t *) GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register GAS_COMEBACK_RSP"); + goto dereg_gas_comeback_req; + } /* WNM BSS Transition Request frame */ - sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + status = sme_register_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, (uint8_t *) WNM_BSS_ACTION_FRAME, WNM_BSS_ACTION_FRAME_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register WNM_BSS_ACTION_FRAME"); + goto dereg_gas_comeback_rsp; + } /* WNM-Notification */ - sme_register_mgmt_frame(hHal, pAdapter->sessionId, type, + status = sme_register_mgmt_frame(hHal, pAdapter->sessionId, type, (uint8_t *) WNM_NOTIFICATION_FRAME, WNM_NOTIFICATION_FRAME_SIZE); + if (status != QDF_STATUS_SUCCESS) { + hdd_err("Failed to register WNM_NOTIFICATION_FRAME"); + goto dereg_wnm_bss_action_frm; + } + +dereg_wnm_bss_action_frm: + sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + (uint8_t *) WNM_BSS_ACTION_FRAME, + WNM_BSS_ACTION_FRAME_SIZE); +dereg_gas_comeback_rsp: + sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + (uint8_t *) GAS_COMEBACK_RSP, + GAS_COMEBACK_RSP_SIZE); +dereg_gas_comeback_req: + sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + (uint8_t *) GAS_COMEBACK_REQ, + GAS_COMEBACK_REQ_SIZE); +dereg_gas_initial_rsp: + sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + (uint8_t *) GAS_INITIAL_RSP, + GAS_INITIAL_RSP_SIZE); +dereg_gas_initial_req: + sme_deregister_mgmt_frame(hHal, SME_SESSION_ID_ANY, type, + (uint8_t *) GAS_INITIAL_REQ, + GAS_INITIAL_REQ_SIZE); +ret_status: + return qdf_status_to_os_return(status); } #else -void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter) +int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter) { tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); /* Register for all P2P action, public action etc frames */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index afd83352d2b8..a814de21c546 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -254,7 +254,18 @@ void wlan_hdd_update_wiphy(hdd_context_t *hdd_ctx); void wlan_hdd_update_11n_mode(struct hdd_config *cfg); int wlan_hdd_cfg80211_register(struct wiphy *wiphy); -void wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter); + +/** + * wlan_hdd_cfg80211_register_frames() - register frame types and callbacks + * with the PE. + * @pAdapter: pointer to adapter + * + * This function is used by HDD to register frame types which are interested + * by supplicant, callbacks for rx frame indication and ack. + * + * Return: 0 on success and non zero value on failure + */ +int wlan_hdd_cfg80211_register_frames(hdd_adapter_t *pAdapter); void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t *pAdapter); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d0d72ae47685..27da64420da4 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -1788,7 +1788,12 @@ int hdd_start_adapter(hdd_adapter_t *adapter) * Action frame registered in one adapter which will * applicable to all interfaces */ - wlan_hdd_cfg80211_register_frames(adapter); + ret = wlan_hdd_cfg80211_register_frames(adapter); + if (ret < 0) { + hdd_err("Failed to register frames - ret %d", ret); + goto err_start_adapter; + } + EXIT(); return 0; err_start_adapter: