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
This commit is contained in:
Ganesh Kondabattini 2017-07-29 12:59:19 +05:30 • committed by snandini
commit 0dc1a6e77a
3 changed files with 86 additions and 12 deletions

View file

@ -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 */

View file

@ -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);

View file

@ -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: