From 22208393bbccb3749be7b1b428e04c6da8262fd8 Mon Sep 17 00:00:00 2001 From: Krunal Soni Date: Fri, 29 Sep 2017 18:10:34 -0700 Subject: [PATCH] qcacld-3.0: Remove SAP connection from policy manager upon stopbss If SAP has no channel left to move then it will issue stop bss. In this scenario, SAP is not cleaning up its entry from policy manager table which causes stale entry left over in table. Fix this situation by stopping the bss successfully and deleting entry from policy manager table. Change-Id: I7c7d305936fe16b0deebb9b7a67f7753cbf243e6 CRs-Fixed: 2112932 --- core/hdd/inc/wlan_hdd_main.h | 1 + core/hdd/src/wlan_hdd_hostapd.c | 50 ++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_main.c | 1 + core/sap/inc/sap_api.h | 1 + core/sap/src/sap_api_link_cntl.c | 4 ++- core/sap/src/sap_fsm.c | 7 +++++ 6 files changed, 63 insertions(+), 1 deletion(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index fd16ce60e998..65950c9ca6b3 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1149,6 +1149,7 @@ struct hdd_adapter { uint8_t snr; struct work_struct monTxWorkQueue; + struct work_struct sap_stop_bss_work; struct sk_buff *skb_to_tx; union { diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index e211ce5a0754..0d821b69d0f6 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1330,6 +1330,47 @@ static void hdd_fill_station_info(struct hdd_station_info *stainfo, stainfo->tx_mcs_map); } +/** + * hdd_stop_sap_due_to_invalid_channel() - to stop sap in case of invalid chnl + * @work: pointer to work structure + * + * Let's say SAP detected RADAR and trying to select the new channel and if no + * valid channel is found due to none of the channels are available or + * regulatory restriction then SAP needs to be stopped. so SAP state-machine + * will create a work to stop the bss + * + * stop bss has to happen through worker thread because radar indication comes + * from FW through mc thread or main host thread and if same thread is used to + * do stopbss then waiting for stopbss to finish operation will halt mc thread + * to freeze which will trigger stopbss timeout. Instead worker thread can do + * the stopbss operation while mc thread waits for stopbss to finish. + * + * Return: none + */ +static void +hdd_stop_sap_due_to_invalid_channel(struct work_struct *work) +{ + /* + * Extract the adapter from work structure. sap_stop_bss_work + * is part of adapter context. + */ + struct hdd_adapter *sap_adapter = container_of(work, + struct hdd_adapter, + sap_stop_bss_work); + hdd_debug("work started for sap session[%d]", sap_adapter->sessionId); + cds_ssr_protect(__func__); + if (sap_adapter == NULL) { + cds_err("sap_adapter is NULL, no work needed"); + cds_ssr_unprotect(__func__); + return; + } + wlan_hdd_stop_sap(sap_adapter); + wlansap_set_invalid_session(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter)); + wlansap_cleanup_cac_timer(WLAN_HDD_GET_SAP_CTX_PTR(sap_adapter)); + hdd_debug("work finished for sap"); + cds_ssr_unprotect(__func__); +} + QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, void *usrDataForCallback) { @@ -2368,6 +2409,14 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, QCA_WLAN_VENDOR_ACS_SELECT_REASON_DFS); return QDF_STATUS_SUCCESS; + case eSAP_STOP_BSS_DUE_TO_NO_CHNL: + hdd_debug("Stop sap session[%d]", + adapter->sessionId); + INIT_WORK(&adapter->sap_stop_bss_work, + hdd_stop_sap_due_to_invalid_channel); + schedule_work(&adapter->sap_stop_bss_work); + return QDF_STATUS_SUCCESS; + default: hdd_debug("SAP message is not handled"); goto stopbss; @@ -8152,6 +8201,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, status = hdd_get_next_adapter(hdd_ctx, pAdapterNode, &pNext); pAdapterNode = pNext; } + cds_flush_work(&adapter->sap_stop_bss_work); /* * When ever stop ap adapter gets called, we need to check * whether any restart AP work is pending. If any restart is pending diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 5a913c6eedb1..a5e817d104fd 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4409,6 +4409,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *ada clear_bit(ACS_PENDING, &adapter->event_flags); } } + cds_flush_work(&adapter->sap_stop_bss_work); /* Any softap specific cleanup here... */ if (adapter->device_mode == QDF_P2P_GO_MODE) wlan_hdd_cleanup_remain_on_channel_ctx(adapter); diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index ec4e82d8350c..44d4fcad2ca2 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -177,6 +177,7 @@ typedef enum { eSAP_DFS_NOL_SET, /* No ch available after DFS RADAR detect */ eSAP_DFS_NO_AVAILABLE_CHANNEL, + eSAP_STOP_BSS_DUE_TO_NO_CHNL, eSAP_ACS_SCAN_SUCCESS_EVENT, eSAP_ACS_CHANNEL_SELECTED, eSAP_ECSA_CHANGE_CHAN_IND, diff --git a/core/sap/src/sap_api_link_cntl.c b/core/sap/src/sap_api_link_cntl.c index 723b9e4d1d73..830b4c7fd03b 100644 --- a/core/sap/src/sap_api_link_cntl.c +++ b/core/sap/src/sap_api_link_cntl.c @@ -1077,7 +1077,9 @@ wlansap_roam_callback(void *ctx, tCsrRoamInfo *csr_roam_info, uint32_t roamId, QDF_TRACE_LEVEL_ERROR, FL("sapdfs: no available channel for sapctx[%pK], StopBss"), pSapContext); - wlansap_stop_bss(pSapContext); + sap_signal_hdd_event(sap_ctx, NULL, + eSAP_STOP_BSS_DUE_TO_NO_CHNL, + (void *) eSAP_STATUS_SUCCESS); } } break; diff --git a/core/sap/src/sap_fsm.c b/core/sap/src/sap_fsm.c index 85f06febda4d..db0972b7ddd3 100644 --- a/core/sap/src/sap_fsm.c +++ b/core/sap/src/sap_fsm.c @@ -2669,6 +2669,13 @@ QDF_STATUS sap_signal_hdd_event(struct sap_context *sap_ctx, __func__, "eSAP_DFS_NEXT_CHANNEL_REQ"); sap_ap_event.sapHddEventCode = eSAP_DFS_NEXT_CHANNEL_REQ; break; + case eSAP_STOP_BSS_DUE_TO_NO_CHNL: + sap_ap_event.sapHddEventCode = eSAP_STOP_BSS_DUE_TO_NO_CHNL; + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_DEBUG, + FL("stopping session_id:%d, bssid:%pM, channel:%d"), + sap_ctx->sessionId, sap_ctx->self_mac_addr, + sap_ctx->channel); + break; default: QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, FL("SAP Unknown callback event = %d"),