qcacld-3.0: Add support for connection failure

Add vdev manager support for connection failure

Change-Id: I996e2bd14c7693793178edffa83d704a57580d93
CRs-Fixed: 2326164
This commit is contained in:
Sandeep Puligilla 2018-10-02 01:00:56 -07:00 • committed by nshrivas
commit 2a7fa8478b
9 changed files with 244 additions and 16 deletions

View file

@ -32,11 +32,13 @@
* @hidden_ssid_restart_in_progress: flag to indicate hidden ssid restart is
* in progress
* @vdev_start_failed: flag to indicate that vdev start failed.
* @connection_fail: flag to indicate connection failed
*/
struct mlme_legacy_priv {
bool chan_switch_in_progress;
bool hidden_ssid_restart_in_progress;
bool vdev_start_failed;
bool connection_fail;
};
/**
@ -107,6 +109,24 @@ bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev);
QDF_STATUS
mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val);
/**
* mlme_is_connection_fail() - get connection fail flag
* @vdev: vdev pointer
*
* Return: value of vdev connection failure flag
*/
bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev);
/**
* mlme_set_connection_fail() - set connection failure flag
* @vdev: vdev pointer
* @val: value to be set
*
* Return: QDF_STATUS
*/
QDF_STATUS
mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val);
/**
* mlme_get_vdev_start_failed() - get mlme priv vdev restart fail flag
* @vdev: vdev pointer

View file

@ -382,7 +382,7 @@ static QDF_STATUS vdevmgr_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
static QDF_STATUS vdevmgr_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
return wma_ap_mlme_vdev_notify_down_complete(vdev_mlme, data_len, data);
return wma_mlme_vdev_notify_down_complete(vdev_mlme, data_len, data);
}
/**
@ -507,6 +507,40 @@ bool ap_mlme_is_hidden_ssid_restart_in_progress(struct wlan_objmgr_vdev *vdev)
return mlme_priv->hidden_ssid_restart_in_progress;
}
QDF_STATUS mlme_set_connection_fail(struct wlan_objmgr_vdev *vdev, bool val)
{
struct vdev_mlme_obj *vdev_mlme;
struct mlme_legacy_priv *mlme_priv;
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme) {
mlme_err("vdev component object is NULL");
return QDF_STATUS_E_FAILURE;
}
mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
mlme_priv->connection_fail = val;
return QDF_STATUS_SUCCESS;
}
bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev)
{
struct vdev_mlme_obj *vdev_mlme;
struct mlme_legacy_priv *mlme_priv;
vdev_mlme = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!vdev_mlme) {
mlme_err("vdev component object is NULL");
return false;
}
mlme_priv = (struct mlme_legacy_priv *)vdev_mlme->legacy_vdev_ptr;
return mlme_priv->connection_fail;
}
QDF_STATUS
mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val)
{

View file

@ -1277,6 +1277,96 @@ static void lim_join_result_callback(tpAniSirGlobal mac, void *param,
qdf_mem_free(link_state_params);
}
#ifdef CONFIG_VDEV_SM
QDF_STATUS lim_sta_send_down_link(join_params *param)
{
tpPESession session;
tpAniSirGlobal mac_ctx;
tpDphHashNode sta_ds = NULL;
if (!param) {
pe_err("param is NULL");
return QDF_STATUS_E_INVAL;
}
mac_ctx = cds_get_context(QDF_MODULE_ID_PE);
if (!mac_ctx) {
pe_err("Mac context is NULL");
return QDF_STATUS_E_INVAL;
}
session = pe_find_session_by_session_id(mac_ctx, param->pe_session_id);
if (!session) {
pe_err("session is NULL");
return QDF_STATUS_E_INVAL;
}
sta_ds = dph_get_hash_entry(mac_ctx, DPH_STA_HASH_INDEX_PEER,
&session->dph.dphHashTable);
if (sta_ds) {
sta_ds->mlmStaContext.disassocReason =
eSIR_MAC_UNSPEC_FAILURE_REASON;
sta_ds->mlmStaContext.cleanupTrigger =
eLIM_JOIN_FAILURE;
sta_ds->mlmStaContext.resultCode = param->result_code;
sta_ds->mlmStaContext.protStatusCode = param->prot_status_code;
/*
* FIX_ME: at the end of lim_cleanup_rx_path,
* make sure PE is sending eWNI_SME_JOIN_RSP
* to SME
*/
lim_cleanup_rx_path(mac_ctx, sta_ds, session);
qdf_mem_free(session->pLimJoinReq);
session->pLimJoinReq = NULL;
/* Cleanup if add bss failed */
if (session->add_bss_failed) {
dph_delete_hash_entry(mac_ctx,
sta_ds->staAddr, sta_ds->assocId,
&session->dph.dphHashTable);
goto error;
}
return QDF_STATUS_SUCCESS;
}
qdf_mem_free(session->pLimJoinReq);
session->pLimJoinReq = NULL;
error:
/*
* Delete the session if JOIN failure occurred.
* if the peer is not created, then there is no
* need to send down the set link state which will
* try to delete the peer. Instead a join response
* failure should be sent to the upper layers.
*/
if (param->result_code != eSIR_SME_PEER_CREATE_FAILED) {
join_params *link_state_arg;
link_state_arg = qdf_mem_malloc(sizeof(*link_state_arg));
if (link_state_arg) {
link_state_arg->result_code = param->result_code;
link_state_arg->prot_status_code =
param->prot_status_code;
link_state_arg->pe_session_id = session->peSessionId;
}
if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
session->bssId,
session->selfMacAddr,
lim_join_result_callback,
link_state_arg) != QDF_STATUS_SUCCESS) {
qdf_mem_free(link_state_arg);
pe_err("Failed to set the LinkState");
}
return QDF_STATUS_SUCCESS;
}
lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
param->result_code,
param->prot_status_code,
session, session->smeSessionId,
session->transactionId);
return QDF_STATUS_SUCCESS;
}
/**
* lim_handle_sme_join_result() - Handles sme join result
* @mac_ctx: Pointer to Global MAC structure
@ -1291,6 +1381,35 @@ static void lim_join_result_callback(tpAniSirGlobal mac, void *param,
*
* Return: None
*/
void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
tSirResultCodes result_code, uint16_t prot_status_code,
tpPESession session)
{
join_params param;
QDF_STATUS status;
if (!session) {
pe_err("session is NULL");
return;
}
if (result_code == eSIR_SME_SUCCESS)
return lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP,
result_code,
prot_status_code, session,
session->smeSessionId,
session->transactionId);
param.result_code = result_code;
param.prot_status_code = prot_status_code;
param.pe_session_id = session->peSessionId;
mlme_set_connection_fail(session->vdev, true);
status = wlan_vdev_mlme_sm_deliver_evt(session->vdev,
WLAN_VDEV_SM_EV_CONNECTION_FAIL,
sizeof(param), &param);
return;
}
#else
void lim_handle_sme_join_result(tpAniSirGlobal mac_ctx,
tSirResultCodes result_code, uint16_t prot_status_code,
tpPESession session_entry)
@ -1356,10 +1475,11 @@ error:
param->prot_status_code = prot_status_code;
param->pe_session_id = session_entry->peSessionId;
}
if (lim_set_link_state
(mac_ctx, eSIR_LINK_DOWN_STATE, session_entry->bssId,
session_entry->selfMacAddr, lim_join_result_callback,
param) != QDF_STATUS_SUCCESS) {
if (lim_set_link_state(mac_ctx, eSIR_LINK_DOWN_STATE,
session_entry->bssId,
session_entry->selfMacAddr,
lim_join_result_callback,
param) != QDF_STATUS_SUCCESS) {
qdf_mem_free(param);
pe_err("Failed to set the LinkState");
}
@ -1369,6 +1489,8 @@ error:
lim_send_sme_join_reassoc_rsp(mac_ctx, eWNI_SME_JOIN_RSP, result_code,
prot_status_code, session_entry, sme_session_id, sme_trans_id);
}
#endif
/**
* lim_process_mlm_add_sta_rsp()

View file

@ -775,6 +775,7 @@ void lim_covert_channel_scan_type(tpAniSirGlobal pMac, uint8_t channelNum,
void lim_set_dfs_channel_list(tpAniSirGlobal pMac, uint8_t channelNum,
tSirDFSChannelList *dfsChannelList);
void limContinueChannelLearn(tpAniSirGlobal);
QDF_STATUS lim_sta_send_down_link(join_params *param);
#ifdef WLAN_FEATURE_11W
/* 11w send SA query request action frame */

View file

@ -8435,7 +8435,24 @@ QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
QDF_STATUS lim_sta_mlme_vdev_stop_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
return lim_sta_send_del_bss((tpPESession)data);
QDF_STATUS status;
bool connection_fail;
if (!data) {
pe_err("event_data is NULL");
return QDF_STATUS_E_INVAL;
}
connection_fail = mlme_is_connection_fail(vdev_mlme->vdev);
pe_info("Send vdev stop, connection_fail %d", connection_fail);
if (connection_fail) {
status = lim_sta_send_down_link((join_params *)data);
mlme_set_connection_fail(vdev_mlme->vdev, false);
} else {
status = lim_sta_send_del_bss((tpPESession)data);
}
return status;
}
void lim_send_beacon(tpAniSirGlobal mac_ctx, tpPESession session)

View file

@ -504,7 +504,7 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_ap_mlme_vdev_notify_down_complete - VDEV init state transition
* wma_mlme_vdev_notify_down_complete - VDEV init state transition
* notification
* @vdev_mlme_obj: VDEV MLME comp object
* @data_len: data size
@ -516,8 +516,8 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
* FAILURE, if it fails due to any
*/
QDF_STATUS
wma_ap_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data);
/**
* wma_ap_mlme_vdev_stop_start_send - handle vdev stop during start req

View file

@ -549,6 +549,15 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
*/
void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req);
/**
* wma_send_set_link_response() - send set link response
* @wma: wma handle
* @req: target request
*
* Return: none
*/
void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req);
/**
* __wma_vdev_stop_resp_handler() - vdev stop response handler
* @handle: wma handle

View file

@ -2026,6 +2026,13 @@ wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
{}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
void wma_send_set_link_response(tp_wma_handle wma, struct wma_target_req *req)
{
tpLinkStateParams params = (tpLinkStateParams) req->user_data;
wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
}
void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req)
{
struct wma_txrx_node *iface;
@ -2248,12 +2255,18 @@ __wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event)
}
}
}
#ifdef CONFIG_VDEV_SM
wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
sizeof(*req_msg), req_msg);
#else
if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to send vdev down cmd: vdev %d",
req_msg->vdev_id);
}
wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
wma_send_set_link_response(wma, req_msg);
#endif
}
free_req_msg:
@ -3207,14 +3220,21 @@ int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
data->generate_rsp);
qdf_mem_free(data);
} else if (req_msg->type == WMA_SET_LINK_PEER_RSP) {
tpLinkStateParams params =
(tpLinkStateParams) req_msg->user_data;
#ifdef CONFIG_VDEV_SM
struct wma_txrx_node *iface =
&wma->interfaces[req_msg->vdev_id];
wlan_vdev_mlme_sm_deliver_evt(iface->vdev,
WLAN_VDEV_SM_EV_MLME_DOWN_REQ,
sizeof(*req_msg), req_msg);
#else
if (wma_send_vdev_down_to_fw(wma, req_msg->vdev_id) !=
QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to send vdev down cmd: vdev %d",
req_msg->vdev_id);
}
wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
wma_send_set_link_response(wma, req_msg);
#endif
} else if (req_msg->type == WMA_DELETE_PEER_RSP) {
#ifdef CONFIG_VDEV_SM
struct wma_txrx_node *iface =

View file

@ -4880,13 +4880,18 @@ QDF_STATUS wma_ap_mlme_vdev_down_send(struct vdev_mlme_obj *vdev_mlme,
}
QDF_STATUS
wma_ap_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
wma_mlme_vdev_notify_down_complete(struct vdev_mlme_obj *vdev_mlme,
uint16_t data_len, void *data)
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
struct wma_target_req *req = (struct wma_target_req *)data;
if (!mlme_get_vdev_start_failed(vdev_mlme->vdev))
wma_send_del_bss_response(wma, (struct wma_target_req *)data);
if (req->msg_type == WMA_SET_LINK_STATE ||
req->type == WMA_SET_LINK_PEER_RSP)
wma_send_set_link_response(wma, req);
else
wma_send_del_bss_response(wma, req);
else
mlme_set_vdev_start_failed(vdev_mlme->vdev, false);