mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 12:58:12 -04:00
qcacld-3.0: Fix error handling in eWNI_SME_ADD_STA_SELF_RSP
When peer creation fails in wma_create_peer, vdev delete is sent to the fw and then eWNI_SME_ADD_STA_SELF_RSP is sent to sme. Here three error cases needs to be handled: 1. The vdev deletion has happened, but the cdp_detach_peer is not done. So the data path peer remains. Also the vdev_active flag that was set after vdev creation was not unset. 2. The eWNI_SME_ADD_STA_SELF_RSP msg handler csr_process_add_sta_session_rsp invokes csr_roam_session_opened which signals HDD that vdev is created successfully and hdd calls hdd_vdev_ready and vdev related parameter set commands are sent to FW for the deleted vdev. 3. Vdev delete is not sent for objmgr peer creation failure in case of VDEV_TYPE_STA and release vdev object ref count. Add cdp_vdev_detach() calls during error case and set the vdev_active flag to false. Handle releasing vdev object ref count in all needed error case flows. Propagate the error in wma_vdev_attach() through csr_roam_session_opened() to HDD and abort the vdev create. Change-Id: Iec97122d011098fae7ae2a59864fbe8ca8a0980e CRs-Fixed: 2322212
This commit is contained in:
parent
b54949b2a0
commit
3551caa95b
5 changed files with 112 additions and 83 deletions
|
|
@ -2742,7 +2742,8 @@ static inline int wlan_hdd_nl_init(struct hdd_context *hdd_ctx)
|
|||
return nl_srv_init(hdd_ctx->wiphy);
|
||||
}
|
||||
#endif
|
||||
QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id);
|
||||
QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
|
||||
QDF_STATUS qdf_status);
|
||||
QDF_STATUS hdd_sme_close_session_callback(uint8_t session_id);
|
||||
|
||||
int hdd_reassoc(struct hdd_adapter *adapter, const uint8_t *bssid,
|
||||
|
|
|
|||
|
|
@ -3913,7 +3913,8 @@ static QDF_STATUS hdd_register_interface(struct hdd_adapter *adapter, bool rtnl_
|
|||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
|
||||
QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id,
|
||||
QDF_STATUS qdf_status)
|
||||
{
|
||||
struct hdd_adapter *adapter;
|
||||
struct hdd_context *hdd_ctx;
|
||||
|
|
@ -3929,7 +3930,10 @@ QDF_STATUS hdd_sme_open_session_callback(uint8_t session_id)
|
|||
hdd_err("NULL adapter for %d", session_id);
|
||||
return QDF_STATUS_E_INVAL;
|
||||
}
|
||||
set_bit(SME_SESSION_OPENED, &adapter->event_flags);
|
||||
|
||||
if (qdf_status == QDF_STATUS_SUCCESS)
|
||||
set_bit(SME_SESSION_OPENED, &adapter->event_flags);
|
||||
|
||||
qdf_event_set(&adapter->qdf_session_open_event);
|
||||
hdd_debug("session %d opened", adapter->session_id);
|
||||
|
||||
|
|
@ -4152,6 +4156,12 @@ int hdd_vdev_create(struct hdd_adapter *adapter,
|
|||
goto hdd_vdev_destroy_procedure;
|
||||
}
|
||||
|
||||
if (!test_bit(SME_SESSION_OPENED, &adapter->event_flags)) {
|
||||
hdd_err("Session failed to open due to vdev create failure");
|
||||
errno = -EINVAL;
|
||||
goto objmgr_vdev_destroy_procedure;
|
||||
}
|
||||
|
||||
/* firmware ready for component communication, raise vdev_ready event */
|
||||
errno = hdd_vdev_ready(adapter);
|
||||
if (errno) {
|
||||
|
|
|
|||
|
|
@ -1599,7 +1599,8 @@ typedef QDF_STATUS (*csr_roam_complete_cb)(void *context,
|
|||
uint32_t roam_id,
|
||||
eRoamCmdStatus roam_status,
|
||||
eCsrRoamResult roam_result);
|
||||
typedef QDF_STATUS (*csr_session_open_cb)(uint8_t session_id);
|
||||
typedef QDF_STATUS (*csr_session_open_cb)(uint8_t session_id,
|
||||
QDF_STATUS qdf_status);
|
||||
typedef QDF_STATUS (*csr_session_close_cb)(uint8_t session_id);
|
||||
|
||||
#define CSR_IS_START_IBSS(pProfile) (eCSR_BSS_TYPE_START_IBSS == \
|
||||
|
|
|
|||
|
|
@ -4071,7 +4071,7 @@ QDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
|
|||
uint32_t roamId,
|
||||
eRoamCmdStatus u1, eCsrRoamResult u2)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
QDF_STATUS ret, status = QDF_STATUS_SUCCESS;
|
||||
#ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR
|
||||
|
||||
WLAN_HOST_DIAG_EVENT_DEF(connectionStatus,
|
||||
|
|
@ -4147,10 +4147,12 @@ QDF_STATUS csr_roam_call_callback(tpAniSirGlobal pMac, uint32_t sessionId,
|
|||
&& (u2 == eCSR_ROAM_RESULT_CHANNEL_CHANGE_SUCCESS)) {
|
||||
pSession->connectedProfile.operationChannel =
|
||||
roam_info->channelChangeRespEvent->newChannelNumber;
|
||||
} else if ((u1 == eCSR_ROAM_SESSION_OPENED) &&
|
||||
(u2 == eCSR_ROAM_RESULT_NONE)) {
|
||||
} else if (u1 == eCSR_ROAM_SESSION_OPENED) {
|
||||
ret = (u2 == eCSR_ROAM_RESULT_SUCCESS) ?
|
||||
QDF_STATUS_SUCCESS : QDF_STATUS_E_FAILURE;
|
||||
|
||||
if (pSession->session_open_cb)
|
||||
pSession->session_open_cb(sessionId);
|
||||
pSession->session_open_cb(sessionId, ret);
|
||||
else
|
||||
sme_err("session_open_cb is not registered");
|
||||
}
|
||||
|
|
@ -16943,16 +16945,23 @@ QDF_STATUS csr_reassoc(tpAniSirGlobal pMac, uint32_t sessionId,
|
|||
}
|
||||
|
||||
static QDF_STATUS csr_roam_session_opened(tpAniSirGlobal pMac,
|
||||
QDF_STATUS qdf_status,
|
||||
uint32_t sessionId)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct csr_roam_info roamInfo;
|
||||
struct csr_roam_info roam_info;
|
||||
|
||||
qdf_mem_set(&roamInfo, sizeof(struct csr_roam_info), 0);
|
||||
status = csr_roam_call_callback(pMac, sessionId, &roamInfo, 0,
|
||||
eCSR_ROAM_SESSION_OPENED,
|
||||
eCSR_ROAM_RESULT_NONE);
|
||||
qdf_mem_set(&roam_info, sizeof(struct csr_roam_info), 0);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(qdf_status)) {
|
||||
status = csr_roam_call_callback(pMac, sessionId, &roam_info, 0,
|
||||
eCSR_ROAM_SESSION_OPENED,
|
||||
eCSR_ROAM_RESULT_FAILURE);
|
||||
} else {
|
||||
status = csr_roam_call_callback(pMac, sessionId, &roam_info, 0,
|
||||
eCSR_ROAM_SESSION_OPENED,
|
||||
eCSR_ROAM_RESULT_SUCCESS);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
@ -16969,26 +16978,31 @@ QDF_STATUS csr_process_add_sta_session_rsp(tpAniSirGlobal pMac, uint8_t *pMsg)
|
|||
rsp = (struct add_sta_self_params *) pMsg;
|
||||
sme_debug("Add Sta self rsp status = %d", rsp->status);
|
||||
|
||||
if (QDF_STATUS_SUCCESS == rsp->status &&
|
||||
(WMI_VDEV_TYPE_STA == rsp->type ||
|
||||
(WMI_VDEV_TYPE_AP == rsp->type &&
|
||||
WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) {
|
||||
sme_debug("send SET IE msg to PE");
|
||||
msg = qdf_mem_malloc(sizeof(*msg));
|
||||
if (NULL == msg) {
|
||||
sme_err("Memory allocation failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
if (QDF_IS_STATUS_SUCCESS(rsp->status)) {
|
||||
if ((WMI_VDEV_TYPE_STA == rsp->type ||
|
||||
(WMI_VDEV_TYPE_AP == rsp->type &&
|
||||
WMI_UNIFIED_VDEV_SUBTYPE_P2P_DEVICE == rsp->sub_type))) {
|
||||
sme_debug("send SET IE msg to PE");
|
||||
msg = qdf_mem_malloc(sizeof(*msg));
|
||||
if (NULL == msg) {
|
||||
sme_err("Memory allocation failed");
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
msg->msg_type = eWNI_SME_SET_IE_REQ;
|
||||
msg->session_id = rsp->session_id;
|
||||
msg->length = sizeof(*msg);
|
||||
status = umac_send_mb_message_to_mac(msg);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
sme_err("Failed to send down the set IE req ");
|
||||
msg->msg_type = eWNI_SME_SET_IE_REQ;
|
||||
msg->session_id = rsp->session_id;
|
||||
msg->length = sizeof(*msg);
|
||||
status = umac_send_mb_message_to_mac(msg);
|
||||
if (!QDF_IS_STATUS_SUCCESS(status))
|
||||
sme_err("Failed to send down the set IE req ");
|
||||
}
|
||||
}
|
||||
|
||||
csr_roam_session_opened(pMac, rsp->session_id);
|
||||
csr_roam_session_opened(pMac, rsp->status, rsp->session_id);
|
||||
|
||||
if (QDF_IS_STATUS_ERROR(rsp->status))
|
||||
csr_cleanup_session(pMac, rsp->session_id);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2366,12 +2366,13 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
params.nss_5g = self_sta_req->nss_5g;
|
||||
|
||||
/* Create a vdev in target */
|
||||
status = wmi_unified_vdev_create_send(wma_handle->wmi_handle,
|
||||
self_sta_req->self_mac_addr,
|
||||
¶ms);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
ret = wmi_unified_vdev_create_send(wma_handle->wmi_handle,
|
||||
self_sta_req->self_mac_addr,
|
||||
¶ms);
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
WMA_LOGE("%s: Unable to add an interface for ath_dev",
|
||||
__func__);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
@ -2389,7 +2390,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
self_sta_req->self_mac_addr,
|
||||
vdev_id, txrx_vdev_type);
|
||||
|
||||
WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %pK", self_sta_req->session_id,
|
||||
WMA_LOGD("vdev_id %hu, txrx_vdev_handle = %pK", vdev_id,
|
||||
txrx_vdev_handle);
|
||||
|
||||
if (!txrx_vdev_handle) {
|
||||
|
|
@ -2404,6 +2405,17 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
wma_handle->interfaces[vdev_id].handle = txrx_vdev_handle;
|
||||
wma_vdev_update_pause_bitmap(vdev_id, 0);
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc, vdev_id,
|
||||
WLAN_LEGACY_WMA_ID);
|
||||
if (!vdev) {
|
||||
WMA_LOGE(FL("vdev obj is NULL for vdev_id: %u"), vdev_id);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
wma_handle->interfaces[vdev_id].vdev_active = false;
|
||||
wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
wma_handle->interfaces[vdev_id].vdev = vdev;
|
||||
wma_handle->interfaces[vdev_id].ptrn_match_enable =
|
||||
wma_handle->ptrn_match_enable_all_vdev ? true : false;
|
||||
|
||||
|
|
@ -2436,9 +2448,9 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
tx_rx_aggregation_size.vdev_id = self_sta_req->session_id;
|
||||
tx_rx_aggregation_size.aggr_type = WMI_VDEV_CUSTOM_AGGR_TYPE_AMPDU;
|
||||
|
||||
status = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
WMA_LOGE("failed to set aggregation sizes(err=%d)", status);
|
||||
ret = wma_set_tx_rx_aggregation_size(&tx_rx_aggregation_size);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
WMA_LOGE("failed to set aggregation sizes(err=%d)", ret);
|
||||
|
||||
tx_rx_aggregation_size.tx_aggregation_size_be =
|
||||
self_sta_req->tx_aggregation_size_be;
|
||||
|
|
@ -2462,11 +2474,10 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
|
||||
switch (self_sta_req->type) {
|
||||
case WMI_VDEV_TYPE_STA:
|
||||
status = wma_set_tx_rx_aggregation_size_per_ac(
|
||||
ret = wma_set_tx_rx_aggregation_size_per_ac(
|
||||
&tx_rx_aggregation_size);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
WMA_LOGE("failed to set aggr sizes per ac(err=%d)",
|
||||
status);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
WMA_LOGE("set aggr sizes per ac(err=%d) failed", ret);
|
||||
|
||||
cfg_val = mac->mlme_cfg->sta.sta_keep_alive_period;
|
||||
wma_set_sta_keep_alive(wma_handle,
|
||||
|
|
@ -2477,57 +2488,59 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
/* offload STA SA query related params to fwr */
|
||||
if (wmi_service_enabled(wma_handle->wmi_handle,
|
||||
wmi_service_sta_pmf_offload)) {
|
||||
wma_set_sta_sa_query_param(wma_handle,
|
||||
self_sta_req->session_id);
|
||||
wma_set_sta_sa_query_param(wma_handle, vdev_id);
|
||||
}
|
||||
|
||||
status = wma_set_sw_retry_threshold(
|
||||
&tx_aggr_sw_retry_threshold);
|
||||
if (status != QDF_STATUS_SUCCESS)
|
||||
WMA_LOGE("failed to set retry threshold(err=%d)",
|
||||
status);
|
||||
ret = wma_set_sw_retry_threshold(&tx_aggr_sw_retry_threshold);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
WMA_LOGE("failed to set retry threshold(err=%d)", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
wma_handle->interfaces[self_sta_req->session_id].type =
|
||||
self_sta_req->type;
|
||||
wma_handle->interfaces[self_sta_req->session_id].sub_type =
|
||||
self_sta_req->sub_type;
|
||||
qdf_atomic_init(&wma_handle->interfaces
|
||||
[self_sta_req->session_id].bss_status);
|
||||
wma_handle->interfaces[vdev_id].type = self_sta_req->type;
|
||||
wma_handle->interfaces[vdev_id].sub_type = self_sta_req->sub_type;
|
||||
qdf_atomic_init(&wma_handle->interfaces[vdev_id].bss_status);
|
||||
|
||||
if (wma_vdev_uses_self_peer(self_sta_req->type,
|
||||
self_sta_req->sub_type)) {
|
||||
status = wma_create_peer(wma_handle, txrx_pdev,
|
||||
txrx_vdev_handle,
|
||||
self_sta_req->self_mac_addr,
|
||||
WMI_PEER_TYPE_DEFAULT,
|
||||
self_sta_req->session_id, false);
|
||||
if (status != QDF_STATUS_SUCCESS) {
|
||||
ret = wma_create_peer(wma_handle, txrx_pdev, txrx_vdev_handle,
|
||||
self_sta_req->self_mac_addr,
|
||||
WMI_PEER_TYPE_DEFAULT,
|
||||
self_sta_req->session_id, false);
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
WMA_LOGE("%s: Failed to create peer", __func__);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
|
||||
wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
|
||||
self_sta_req->session_id);
|
||||
wma_handle->interfaces[vdev_id].vdev_active = false;
|
||||
wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
|
||||
wma_handle->interfaces[vdev_id].vdev = NULL;
|
||||
goto end;
|
||||
}
|
||||
} else if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
|
||||
obj_peer = wma_create_objmgr_peer(wma_handle,
|
||||
vdev_id,
|
||||
obj_peer = wma_create_objmgr_peer(wma_handle, vdev_id,
|
||||
self_sta_req->self_mac_addr,
|
||||
WMI_PEER_TYPE_DEFAULT);
|
||||
if (!obj_peer) {
|
||||
WMA_LOGE("%s: Failed to create obj mgr peer for self sta",
|
||||
__func__);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
wmi_unified_vdev_delete_send(wma_handle->wmi_handle,
|
||||
self_sta_req->session_id);
|
||||
wma_handle->interfaces[vdev_id].vdev_active = false;
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_WMA_ID);
|
||||
wma_handle->interfaces[vdev_id].vdev = NULL;
|
||||
wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
WMA_LOGD("Setting WMI_VDEV_PARAM_DISCONNECT_TH: %d",
|
||||
self_sta_req->pkt_err_disconn_th);
|
||||
ret = wma_vdev_set_param(wma_handle->wmi_handle,
|
||||
self_sta_req->session_id,
|
||||
WMI_VDEV_PARAM_DISCONNECT_TH,
|
||||
self_sta_req->pkt_err_disconn_th);
|
||||
self_sta_req->pkt_err_disconn_th);
|
||||
ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
|
||||
WMI_VDEV_PARAM_DISCONNECT_TH,
|
||||
self_sta_req->pkt_err_disconn_th);
|
||||
if (ret)
|
||||
WMA_LOGE("Failed to set WMI_VDEV_PARAM_DISCONNECT_TH");
|
||||
|
||||
|
|
@ -2538,8 +2551,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
WMA_LOGE("Failed to set WMI VDEV MCC_RTSCTS_PROTECTION_ENABLE");
|
||||
|
||||
ret = wma_vdev_set_param(wma_handle->wmi_handle,
|
||||
self_sta_req->session_id,
|
||||
ret = wma_vdev_set_param(wma_handle->wmi_handle, vdev_id,
|
||||
WMI_VDEV_PARAM_MCC_BROADCAST_PROBE_ENABLE,
|
||||
mac->roam.configParam.mcc_bcast_prob_resp_enable);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
|
|
@ -2655,7 +2667,7 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
WMA_LOGD("%s: setting ini value for WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED: %d",
|
||||
__func__, cfg_val);
|
||||
ret = wma_set_enable_disable_mcc_adaptive_scheduler(cfg_val);
|
||||
if (ret != QDF_STATUS_SUCCESS) {
|
||||
if (QDF_IS_STATUS_ERROR(ret)) {
|
||||
WMA_LOGE("Failed to set WNI_CFG_ENABLE_MCC_ADAPTIVE_SCHED");
|
||||
}
|
||||
} else {
|
||||
|
|
@ -2663,21 +2675,12 @@ struct cdp_vdev *wma_vdev_attach(tp_wma_handle wma_handle,
|
|||
}
|
||||
|
||||
if (self_sta_req->type == WMI_VDEV_TYPE_STA) {
|
||||
status = wma_config_active_apf_mode(wma_handle,
|
||||
self_sta_req->session_id);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
ret = wma_config_active_apf_mode(wma_handle,
|
||||
self_sta_req->session_id);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
WMA_LOGE("Failed to configure active APF mode");
|
||||
}
|
||||
|
||||
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(wma_handle->psoc,
|
||||
vdev_id,
|
||||
WLAN_LEGACY_WMA_ID);
|
||||
if (!vdev) {
|
||||
WMA_LOGE(FL("vdev obj is NULL for vdev_id: %u"), vdev_id);
|
||||
status = QDF_STATUS_E_FAILURE;
|
||||
} else {
|
||||
wma_handle->interfaces[vdev_id].vdev = vdev;
|
||||
}
|
||||
end:
|
||||
self_sta_req->status = status;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue