qcacld-3.0: Refactor mlme code to integrate SAP stop vdev SM

Divide and refactor mlme functions to integrate vdev state
machine for SAP stop.

Change-Id: Id9841b1a87f2f3c1c2816dae8b2a183ac04791a9
CRs-Fixed: 2309264
This commit is contained in:
Abhishek Singh
2018-08-30 17:45:59 +05:30
committed by nshrivas
parent dfa69c397a
commit 2904a6ac79
4 changed files with 193 additions and 78 deletions

View File

@@ -2881,18 +2881,85 @@ static void __lim_counter_measures(tpAniSirGlobal pMac, tpPESession psessionEntr
mac, psessionEntry, false);
};
/**
* lim_send_stop_bss_failure_resp() -send failure delete bss resp to sme
* @mac_ctx: mac ctx
* @session: session pointer
*
* Return None
*/
static void lim_send_stop_bss_failure_resp(tpAniSirGlobal mac_ctx,
tpPESession session)
{
session->limSmeState = session->limPrevSmeState;
MTRACE(mac_trace(mac_ctx, TRACE_CODE_SME_STATE, session->peSessionId,
session->limSmeState));
lim_send_sme_rsp(mac_ctx, eWNI_SME_STOP_BSS_RSP,
eSIR_SME_STOP_BSS_FAILURE, session->smeSessionId,
session->transactionId);
}
void lim_delete_all_peers(tpPESession session)
{
uint8_t i = 0;
tpAniSirGlobal mac_ctx = session->mac_ctx;
tpDphHashNode sta_ds = NULL;
QDF_STATUS status;
for (i = 1; i < session->dph.dphHashTable.size; i++) {
sta_ds = dph_get_hash_entry(mac_ctx, i,
&session->dph.dphHashTable);
if (!sta_ds)
continue;
status = lim_del_sta(mac_ctx, sta_ds, false, session);
if (QDF_STATUS_SUCCESS == status) {
lim_delete_dph_hash_entry(mac_ctx, sta_ds->staAddr,
sta_ds->assocId, session);
lim_release_peer_idx(mac_ctx, sta_ds->assocId, session);
} else {
pe_err("lim_del_sta failed with Status: %d", status);
QDF_ASSERT(0);
}
}
}
void lim_send_vdev_stop(tpPESession session)
{
tpAniSirGlobal mac_ctx = session->mac_ctx;
QDF_STATUS status;
status = lim_del_bss(mac_ctx, NULL, session->bssIdx, session);
if (QDF_IS_STATUS_ERROR(status)) {
pe_err("delBss failed for bss %d", session->bssIdx);
lim_send_stop_bss_failure_resp(mac_ctx, session);
}
}
/**
* lim_delete_peers_and_send_vdev_stop() -delete peers and send vdev stop
* @session: session pointer
*
* Return None
*/
static void lim_delete_peers_and_send_vdev_stop(tpPESession session)
{
lim_delete_all_peers(session);
/* send a delBss to HAL and wait for a response */
lim_send_vdev_stop(session);
}
static void
__lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{
tSirSmeStopBssReq stopBssReq;
QDF_STATUS status;
tLimSmeStates prevState;
tpPESession psessionEntry;
uint8_t smesessionId;
uint8_t sessionId;
uint16_t smetransactionId;
uint8_t i = 0;
tpDphHashNode pStaDs = NULL;
qdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq));
smesessionId = stopBssReq.sessionId;
@@ -2947,6 +3014,7 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
stopBssReq.reasonCode);
prevState = psessionEntry->limSmeState;
psessionEntry->limPrevSmeState = prevState;
psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
MTRACE(mac_trace
@@ -2991,36 +3059,9 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
*/
pMac->lim.gLimIbssCoalescingHappened = false;
}
for (i = 1; i < psessionEntry->dph.dphHashTable.size; i++) {
pStaDs =
dph_get_hash_entry(pMac, i, &psessionEntry->dph.dphHashTable);
if (NULL == pStaDs)
continue;
status = lim_del_sta(pMac, pStaDs, false, psessionEntry);
if (QDF_STATUS_SUCCESS == status) {
lim_delete_dph_hash_entry(pMac, pStaDs->staAddr,
pStaDs->assocId, psessionEntry);
lim_release_peer_idx(pMac, pStaDs->assocId, psessionEntry);
} else {
pe_err("lim_del_sta failed with Status: %d", status);
QDF_ASSERT(0);
}
}
/* send a delBss to HAL and wait for a response */
status = lim_del_bss(pMac, NULL, psessionEntry->bssIdx, psessionEntry);
if (status != QDF_STATUS_SUCCESS) {
pe_err("delBss failed for bss %d", psessionEntry->bssIdx);
psessionEntry->limSmeState = prevState;
lim_delete_peers_and_send_vdev_stop(psessionEntry);
MTRACE(mac_trace
(pMac, TRACE_CODE_SME_STATE, psessionEntry->peSessionId,
psessionEntry->limSmeState));
lim_send_sme_rsp(pMac, eWNI_SME_STOP_BSS_RSP,
eSIR_SME_STOP_BSS_FAILURE, smesessionId,
smetransactionId);
}
}
/**

View File

@@ -1360,6 +1360,23 @@ void lim_send_dfs_chan_sw_ie_update(tpAniSirGlobal mac_ctx,
*/
void lim_process_ap_ecsa_timeout(void *session);
/**
* lim_delete_all_peers() -delete all connected peers
* @session: session pointer
*
* Return None
*/
void lim_delete_all_peers(tpPESession session);
/**
* lim_send_vdev_stop() -send delete bss/stop vdev req
* @session: session pointer
*
* Return None
*/
void lim_send_vdev_stop(tpPESession session);
/**
* lim_send_chan_switch_action_frame()- Send an action frame
* containing CSA IE or ECSA IE depending on the connected

View File

@@ -540,6 +540,33 @@ QDF_STATUS wma_create_peer(tp_wma_handle wma, struct cdp_pdev *pdev,
uint32_t peer_type, uint8_t vdev_id,
bool roam_synch_in_progress);
/**
* wma_send_del_bss_response() - send delete bss resp
* @wma: wma handle
* @req: target request
*
* Return: none
*/
void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req);
/**
* __wma_vdev_stop_resp_handler() - vdev stop response handler
* @handle: wma handle
* @cmd_param_info: event buffer
* @len: buffer length
*
* Return: QDF_STATUS_SUCCESS for success or QDF_ERROR code
*/
QDF_STATUS
__wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event);
/**
* wma_vdev_stop_resp_handler() - vdev stop response handler
* @handle: wma handle
* @cmd_param_info: event buffer
* @len: buffer length
*
* Return: 0 for success or error code
*/
int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
u32 len);

View File

@@ -1953,22 +1953,12 @@ wma_check_and_find_mcc_ap(tp_wma_handle wma, uint8_t vdev_id)
{}
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
/**
* wma_send_del_bss_response() - send del bss resp to upper layer
* @wma: wma handle.
* @vdev_id: vdev ID of device for which MCC has to be checked
*
* This function sends del bss resp to upper layer
*
* Return: none
*/
static void
wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
uint8_t vdev_id)
void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req)
{
struct wma_txrx_node *iface;
struct beacon_info *bcn;
tpDeleteBssParams params;
uint8_t vdev_id;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
if (!req) {
@@ -1976,6 +1966,7 @@ wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
return;
}
vdev_id = req->vdev_id;
iface = &wma->interfaces[vdev_id];
if (!iface->handle) {
WMA_LOGE("%s vdev id %d is already deleted",
@@ -1987,12 +1978,6 @@ wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
}
params = (tpDeleteBssParams)req->user_data;
if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id);
} else {
wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_STOP);
wma_check_and_find_mcc_ap(wma, vdev_id);
}
cdp_fc_vdev_flush(soc, iface->handle);
WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp",
@@ -2040,41 +2025,51 @@ wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
}
/**
* wma_vdev_stop_resp_handler() - vdev stop response handler
* @handle: wma handle
* @cmd_param_info: event buffer
* @len: buffer length
* wma_send_del_bss_response() - send del bss resp to upper layer
* @wma: wma handle.
* @vdev_id: vdev ID of device for which MCC has to be checked
*
* Return: 0 for success or error code
* This function sends del bss resp to upper layer
*
* Return: none
*/
int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
u32 len)
static void
wma_send_vdev_down_bss(tp_wma_handle wma, struct wma_target_req *req)
{
tp_wma_handle wma = (tp_wma_handle) handle;
WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
wmi_vdev_stopped_event_fixed_param *resp_event;
uint8_t vdev_id;
if (!req) {
WMA_LOGE("%s req is NULL", __func__);
return;
}
vdev_id = req->vdev_id;
if (wma_send_vdev_down_to_fw(wma, vdev_id) != QDF_STATUS_SUCCESS) {
WMA_LOGE("Failed to send vdev down cmd: vdev %d", vdev_id);
} else {
wma_vdev_set_mlme_state(wma, vdev_id, WLAN_VDEV_S_STOP);
wma_check_and_find_mcc_ap(wma, vdev_id);
}
wma_send_del_bss_response(wma, req);
}
QDF_STATUS
__wma_vdev_stop_resp_handler(wmi_vdev_stopped_event_fixed_param *resp_event)
{
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
struct wma_target_req *req_msg, *del_req;
struct cdp_pdev *pdev;
void *peer = NULL;
uint8_t peer_id;
struct wma_txrx_node *iface;
int32_t status = 0;
int status = 0;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
WMA_LOGD("%s: Enter", __func__);
param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
WMA_LOGE("Invalid event buffer");
return -EINVAL;
}
resp_event = param_buf->fixed_param;
if (resp_event->vdev_id >= wma->max_bssid) {
WMA_LOGE("%s: Invalid vdev_id %d from FW",
__func__, resp_event->vdev_id);
return -EINVAL;
if (!wma) {
WMA_LOGE("%s: wma is null", __func__);
return QDF_STATUS_E_INVAL;
}
iface = &wma->interfaces[resp_event->vdev_id];
@@ -2099,7 +2094,7 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
if (!req_msg) {
WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d",
__func__, resp_event->vdev_id);
return -EINVAL;
return QDF_STATUS_E_INVAL;
}
pdev = cds_get_context(QDF_MODULE_ID_TXRX);
@@ -2144,7 +2139,7 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
wmi_service_sync_delete_cmds))
goto free_req_msg;
wma_send_del_bss_response(wma, req_msg, resp_event->vdev_id);
wma_send_vdev_down_bss(wma, req_msg);
} else if (req_msg->msg_type == WMA_SET_LINK_STATE) {
tpLinkStateParams params =
(tpLinkStateParams) req_msg->user_data;
@@ -2190,7 +2185,42 @@ free_req_msg:
PEER_DEBUG_ID_WMA_VDEV_STOP_RESP);
qdf_mc_timer_destroy(&req_msg->event_timeout);
qdf_mem_free(req_msg);
return status;
if (status)
return QDF_STATUS_E_INVAL;
else
return QDF_STATUS_SUCCESS;
}
int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
u32 len)
{
tp_wma_handle wma = (tp_wma_handle) handle;
WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
wmi_vdev_stopped_event_fixed_param *resp_event;
int32_t status = 0;
WMA_LOGD("%s: Enter", __func__);
param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info;
if (!param_buf) {
WMA_LOGE("Invalid event buffer");
return -EINVAL;
}
resp_event = param_buf->fixed_param;
if (resp_event->vdev_id >= wma->max_bssid) {
WMA_LOGE("%s: Invalid vdev_id %d from FW",
__func__, resp_event->vdev_id);
return -EINVAL;
}
status = __wma_vdev_stop_resp_handler(resp_event);
if (QDF_IS_STATUS_ERROR(status))
return -EINVAL;
return 0;
}
/**
@@ -3106,7 +3136,7 @@ int wma_peer_delete_handler(void *handle, uint8_t *cmd_param_info,
}
wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
} else if (req_msg->type == WMA_DELETE_PEER_RSP) {
wma_send_del_bss_response(wma, req_msg, req_msg->vdev_id);
wma_send_vdev_down_bss(wma, req_msg);
}
qdf_mem_free(req_msg);
return status;