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); 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 static void
__lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf) __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
{ {
tSirSmeStopBssReq stopBssReq; tSirSmeStopBssReq stopBssReq;
QDF_STATUS status;
tLimSmeStates prevState; tLimSmeStates prevState;
tpPESession psessionEntry; tpPESession psessionEntry;
uint8_t smesessionId; uint8_t smesessionId;
uint8_t sessionId; uint8_t sessionId;
uint16_t smetransactionId; uint16_t smetransactionId;
uint8_t i = 0;
tpDphHashNode pStaDs = NULL;
qdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq)); qdf_mem_copy(&stopBssReq, pMsgBuf, sizeof(tSirSmeStopBssReq));
smesessionId = stopBssReq.sessionId; smesessionId = stopBssReq.sessionId;
@@ -2947,6 +3014,7 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
stopBssReq.reasonCode); stopBssReq.reasonCode);
prevState = psessionEntry->limSmeState; prevState = psessionEntry->limSmeState;
psessionEntry->limPrevSmeState = prevState;
psessionEntry->limSmeState = eLIM_SME_IDLE_STATE; psessionEntry->limSmeState = eLIM_SME_IDLE_STATE;
MTRACE(mac_trace MTRACE(mac_trace
@@ -2991,36 +3059,9 @@ __lim_handle_sme_stop_bss_request(tpAniSirGlobal pMac, uint32_t *pMsgBuf)
*/ */
pMac->lim.gLimIbssCoalescingHappened = false; 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) { lim_delete_peers_and_send_vdev_stop(psessionEntry);
pe_err("delBss failed for bss %d", psessionEntry->bssIdx);
psessionEntry->limSmeState = prevState;
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); 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 * lim_send_chan_switch_action_frame()- Send an action frame
* containing CSA IE or ECSA IE depending on the connected * 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, uint32_t peer_type, uint8_t vdev_id,
bool roam_synch_in_progress); 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, int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
u32 len); 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 */ #endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
/** void wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req)
* 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)
{ {
struct wma_txrx_node *iface; struct wma_txrx_node *iface;
struct beacon_info *bcn; struct beacon_info *bcn;
tpDeleteBssParams params; tpDeleteBssParams params;
uint8_t vdev_id;
void *soc = cds_get_context(QDF_MODULE_ID_SOC); void *soc = cds_get_context(QDF_MODULE_ID_SOC);
if (!req) { if (!req) {
@@ -1976,6 +1966,7 @@ wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
return; return;
} }
vdev_id = req->vdev_id;
iface = &wma->interfaces[vdev_id]; iface = &wma->interfaces[vdev_id];
if (!iface->handle) { if (!iface->handle) {
WMA_LOGE("%s vdev id %d is already deleted", 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; 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); cdp_fc_vdev_flush(soc, iface->handle);
WMA_LOGD("%s, vdev_id: %d, un-pausing tx_ll_queue for VDEV_STOP rsp", 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 * wma_send_del_bss_response() - send del bss resp to upper layer
* @handle: wma handle * @wma: wma handle.
* @cmd_param_info: event buffer * @vdev_id: vdev ID of device for which MCC has to be checked
* @len: buffer length
* *
* 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, static void
u32 len) wma_send_vdev_down_bss(tp_wma_handle wma, struct wma_target_req *req)
{ {
tp_wma_handle wma = (tp_wma_handle) handle; uint8_t vdev_id;
WMI_VDEV_STOPPED_EVENTID_param_tlvs *param_buf;
wmi_vdev_stopped_event_fixed_param *resp_event; 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 wma_target_req *req_msg, *del_req;
struct cdp_pdev *pdev; struct cdp_pdev *pdev;
void *peer = NULL; void *peer = NULL;
uint8_t peer_id; uint8_t peer_id;
struct wma_txrx_node *iface; struct wma_txrx_node *iface;
int32_t status = 0; int status = 0;
void *soc = cds_get_context(QDF_MODULE_ID_SOC); void *soc = cds_get_context(QDF_MODULE_ID_SOC);
WMA_LOGD("%s: Enter", __func__); if (!wma) {
WMA_LOGE("%s: wma is null", __func__);
param_buf = (WMI_VDEV_STOPPED_EVENTID_param_tlvs *) cmd_param_info; return QDF_STATUS_E_INVAL;
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;
} }
iface = &wma->interfaces[resp_event->vdev_id]; 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) { if (!req_msg) {
WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d", WMA_LOGE("%s: Failed to lookup vdev request for vdev id %d",
__func__, resp_event->vdev_id); __func__, resp_event->vdev_id);
return -EINVAL; return QDF_STATUS_E_INVAL;
} }
pdev = cds_get_context(QDF_MODULE_ID_TXRX); 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)) wmi_service_sync_delete_cmds))
goto free_req_msg; 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) { } else if (req_msg->msg_type == WMA_SET_LINK_STATE) {
tpLinkStateParams params = tpLinkStateParams params =
(tpLinkStateParams) req_msg->user_data; (tpLinkStateParams) req_msg->user_data;
@@ -2190,7 +2185,42 @@ free_req_msg:
PEER_DEBUG_ID_WMA_VDEV_STOP_RESP); PEER_DEBUG_ID_WMA_VDEV_STOP_RESP);
qdf_mc_timer_destroy(&req_msg->event_timeout); qdf_mc_timer_destroy(&req_msg->event_timeout);
qdf_mem_free(req_msg); 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); wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
} else if (req_msg->type == WMA_DELETE_PEER_RSP) { } 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); qdf_mem_free(req_msg);
return status; return status;