qcacld-3.0: Use stop adapter during SSR

Presently, during Subsystem Restart(SSR) the object references
are not released cleanly, invoke stop adapter during the SSR
to have common functionality between the netdevice going down
and SSR.

Change-Id: I2980379022f62ef27dea92868c8033c087544d50
CRs-Fixed: 2587443
This commit is contained in:
Arun Kumar Khandavalli 2019-12-09 15:06:28 +05:30 committed by nshrivas
parent 9e23ab47ae
commit 3801c4f263
9 changed files with 87 additions and 256 deletions

View File

@ -1230,11 +1230,6 @@ QDF_STATUS cds_close(struct wlan_objmgr_psoc *psoc)
} }
gp_cds_context->mac_context = NULL; gp_cds_context->mac_context = NULL;
/*
* Call this before cdp soc detatch as it used the cdp soc to free the
* cdp vdev if any.
*/
wma_release_pending_vdev_refs();
cdp_soc_detach(gp_cds_context->dp_soc); cdp_soc_detach(gp_cds_context->dp_soc);
gp_cds_context->dp_soc = NULL; gp_cds_context->dp_soc = NULL;

View File

@ -3303,19 +3303,19 @@ QDF_STATUS hdd_init_ap_mode(struct hdd_adapter *adapter, bool reinit)
status = qdf_event_create(&phostapdBuf->qdf_event); status = qdf_event_create(&phostapdBuf->qdf_event);
if (!QDF_IS_STATUS_SUCCESS(status)) { if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Hostapd HDD qdf event init failed!!"); hdd_err("Hostapd HDD qdf event init failed!!");
goto error_release_sap_session; goto error_deinit_sap_session;
} }
status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event); status = qdf_event_create(&phostapdBuf->qdf_stop_bss_event);
if (!QDF_IS_STATUS_SUCCESS(status)) { if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Hostapd HDD stop bss event init failed!!"); hdd_err("Hostapd HDD stop bss event init failed!!");
goto error_release_sap_session; goto error_deinit_sap_session;
} }
status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event); status = qdf_event_create(&phostapdBuf->qdf_sta_disassoc_event);
if (!QDF_IS_STATUS_SUCCESS(status)) { if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Hostapd HDD sta disassoc event init failed!!"); hdd_err("Hostapd HDD sta disassoc event init failed!!");
goto error_release_sap_session; goto error_deinit_sap_session;
} }
/* Register as a wireless device */ /* Register as a wireless device */
@ -3383,13 +3383,11 @@ error_release_wmm:
error_release_sta_info: error_release_sta_info:
hdd_sta_info_deinit(&adapter->sta_info_list); hdd_sta_info_deinit(&adapter->sta_info_list);
error_release_softap_tx_rx: error_release_softap_tx_rx:
hdd_softap_deinit_tx_rx(adapter);
error_release_sap_session:
hdd_unregister_wext(adapter->dev); hdd_unregister_wext(adapter->dev);
hdd_softap_deinit_tx_rx(adapter);
error_deinit_sap_session:
hdd_hostapd_deinit_sap_session(adapter); hdd_hostapd_deinit_sap_session(adapter);
error_release_vdev: error_release_vdev:
QDF_BUG(!hdd_vdev_destroy(adapter));
hdd_exit(); hdd_exit();
return status; return status;
} }

View File

@ -5948,6 +5948,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
if (!wlan_sap_is_pre_cac_context(sap_ctx) && if (!wlan_sap_is_pre_cac_context(sap_ctx) &&
(hdd_ctx->sap_pre_cac_work.fn)) (hdd_ctx->sap_pre_cac_work.fn))
cds_flush_work(&hdd_ctx->sap_pre_cac_work); cds_flush_work(&hdd_ctx->sap_pre_cac_work);
wlansap_cleanup_cac_timer(sap_ctx);
/* fallthrough */ /* fallthrough */
@ -6022,9 +6023,16 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
/* Reset WNI_CFG_PROBE_RSP Flags */ /* Reset WNI_CFG_PROBE_RSP Flags */
wlan_hdd_reset_prob_rspies(adapter); wlan_hdd_reset_prob_rspies(adapter);
} }
clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
qdf_mem_free(adapter->session.ap.beacon); /*
adapter->session.ap.beacon = NULL; * Note to restart sap after SSR driver needs below information
* and is not cleared/freed on purpose in case of SAP SSR
*/
if (!cds_is_driver_recovering()) {
clear_bit(SOFTAP_INIT_DONE, &adapter->event_flags);
qdf_mem_free(adapter->session.ap.beacon);
adapter->session.ap.beacon = NULL;
}
/* Clear all the cached sta info */ /* Clear all the cached sta info */
hdd_clear_cached_sta_info(&adapter->cache_sta_info_list); hdd_clear_cached_sta_info(&adapter->cache_sta_info_list);
@ -6045,7 +6053,7 @@ QDF_STATUS hdd_stop_adapter(struct hdd_context *hdd_ctx,
cancel_work_sync(&adapter->ipv6_notifier_work); cancel_work_sync(&adapter->ipv6_notifier_work);
#endif #endif
#endif #endif
sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
hdd_vdev_destroy(adapter); hdd_vdev_destroy(adapter);
mutex_unlock(&hdd_ctx->sap_lock); mutex_unlock(&hdd_ctx->sap_lock);
@ -6162,31 +6170,30 @@ static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
qdf_mc_timer_stop(&adapter->tx_flow_control_timer); qdf_mc_timer_stop(&adapter->tx_flow_control_timer);
} }
} }
#else
static void hdd_adapter_abort_tx_flow(struct hdd_adapter *adapter)
{
}
#endif #endif
QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx) QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
{ {
struct hdd_adapter *adapter; struct hdd_adapter *adapter;
struct hdd_station_ctx *sta_ctx;
struct qdf_mac_addr peer_macaddr;
bool value; bool value;
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
hdd_enter(); hdd_enter();
/* do not flush work if it is not created */ ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
if (hdd_ctx->sap_pre_cac_work.fn)
cds_flush_work(&hdd_ctx->sap_pre_cac_work);
hdd_for_each_adapter(hdd_ctx, adapter) { hdd_for_each_adapter(hdd_ctx, adapter) {
hdd_info("[SSR] reset adapter with device mode %s(%d)", hdd_info("[SSR] reset adapter with device mode %s(%d)",
qdf_opmode_str(adapter->device_mode), qdf_opmode_str(adapter->device_mode),
adapter->device_mode); adapter->device_mode);
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
hdd_adapter_abort_tx_flow(adapter);
#endif
hdd_adapter_abort_tx_flow(adapter);
if ((adapter->device_mode == QDF_STA_MODE) || if ((adapter->device_mode == QDF_STA_MODE) ||
(adapter->device_mode == QDF_P2P_CLIENT_MODE)) { (adapter->device_mode == QDF_P2P_CLIENT_MODE)) {
/* Stop tdls timers */ /* Stop tdls timers */
@ -6195,9 +6202,8 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
hdd_notify_tdls_reset_adapter(vdev); hdd_notify_tdls_reset_adapter(vdev);
hdd_objmgr_put_vdev(vdev); hdd_objmgr_put_vdev(vdev);
} }
adapter->session.station.hdd_reassoc_scenario = false;
} }
ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
if (value && if (value &&
adapter->device_mode == QDF_SAP_MODE) { adapter->device_mode == QDF_SAP_MODE) {
wlan_hdd_netif_queue_control(adapter, wlan_hdd_netif_queue_control(adapter,
@ -6209,13 +6215,6 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
WLAN_CONTROL_PATH); WLAN_CONTROL_PATH);
} }
if ((adapter->device_mode == QDF_P2P_GO_MODE ||
adapter->device_mode == QDF_SAP_MODE) &&
test_bit(SOFTAP_BSS_STARTED, &adapter->event_flags)) {
hdd_sap_indicate_disconnect_for_sta(adapter);
clear_bit(SOFTAP_BSS_STARTED, &adapter->event_flags);
}
/* /*
* Clear fc flag if it was set before SSR to avoid TX queues * Clear fc flag if it was set before SSR to avoid TX queues
* permanently stopped after SSR. * permanently stopped after SSR.
@ -6228,73 +6227,19 @@ QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx)
WLAN_DATA_FLOW_CONTROL); WLAN_DATA_FLOW_CONTROL);
hdd_reset_scan_operation(hdd_ctx, adapter); hdd_reset_scan_operation(hdd_ctx, adapter);
hdd_deinit_tx_rx(adapter); hdd_deinit_tx_rx(adapter);
policy_mgr_decr_session_set_pcl(hdd_ctx->psoc,
adapter->device_mode, adapter->vdev_id);
hdd_green_ap_start_state_mc(hdd_ctx, adapter->device_mode,
false);
if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) { if (test_bit(WMM_INIT_DONE, &adapter->event_flags)) {
hdd_wmm_adapter_close(adapter); hdd_wmm_adapter_close(adapter);
clear_bit(WMM_INIT_DONE, &adapter->event_flags); clear_bit(WMM_INIT_DONE, &adapter->event_flags);
} }
if (adapter->device_mode == QDF_STA_MODE)
hdd_clear_fils_connection_info(adapter);
if (adapter->device_mode == QDF_SAP_MODE) {
wlansap_cleanup_cac_timer(
WLAN_HDD_GET_SAP_CTX_PTR(adapter));
/*
* If adapter is SAP, set session ID to invalid
* since SAP session will be cleanup during SSR.
*/
wlansap_set_invalid_session(
WLAN_HDD_GET_SAP_CTX_PTR(adapter));
}
/* Release vdev ref count to avoid vdev object leak */
if (adapter->device_mode == QDF_P2P_GO_MODE ||
adapter->device_mode == QDF_SAP_MODE)
wlansap_release_vdev_ref(
WLAN_HDD_GET_SAP_CTX_PTR(adapter));
/* Delete connection peers if any to avoid peer object leaks */
if (adapter->device_mode == QDF_STA_MODE ||
adapter->device_mode == QDF_P2P_CLIENT_MODE) {
sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
qdf_copy_macaddr(&peer_macaddr,
&sta_ctx->conn_info.bssid);
}
hdd_nud_ignore_tracking(adapter, true);
hdd_nud_reset_tracking(adapter);
hdd_nud_flush_work(adapter);
hdd_mic_flush_work(adapter);
if (adapter->device_mode != QDF_SAP_MODE && if (adapter->device_mode != QDF_SAP_MODE &&
adapter->device_mode != QDF_P2P_GO_MODE && adapter->device_mode != QDF_P2P_GO_MODE &&
adapter->device_mode != QDF_FTM_MODE) adapter->device_mode != QDF_FTM_MODE)
hdd_set_disconnect_status(adapter, false); hdd_set_disconnect_status(adapter, false);
hdd_stop_tsf_sync(adapter); hdd_stop_adapter(hdd_ctx, adapter);
hdd_softap_deinit_tx_rx(adapter);
if (adapter->device_mode == QDF_SAP_MODE ||
adapter->device_mode == QDF_P2P_GO_MODE) {
/* Clear all the cached sta info */
hdd_clear_cached_sta_info(
&adapter->cache_sta_info_list);
hdd_sta_info_deinit(&adapter->sta_info_list);
hdd_sta_info_deinit(&adapter->cache_sta_info_list);
}
hdd_deregister_hl_netdev_fc_timer(adapter);
hdd_deregister_tx_flow_control(adapter);
/* Destroy vdev which will be recreated during reinit. */
hdd_vdev_destroy(adapter);
} }
hdd_exit(); hdd_exit();
@ -10540,8 +10485,17 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter)
ret = hdd_vdev_create(adapter); ret = hdd_vdev_create(adapter);
if (ret) { if (ret) {
hdd_err("failed to create vdev, status:%d", ret); hdd_err("failed to create vdev, status:%d", ret);
hdd_sap_destroy_ctx(adapter); goto sap_destroy_ctx;
return ret; }
status = sap_acquire_vdev_ref(hdd_ctx->psoc,
WLAN_HDD_GET_SAP_CTX_PTR(adapter),
adapter->vdev_id);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Failed to get vdev ref for sap for session_id: %u",
adapter->vdev_id);
ret = qdf_status_to_os_return(status);
goto sap_vdev_destroy;
} }
if (adapter->device_mode == QDF_SAP_MODE) { if (adapter->device_mode == QDF_SAP_MODE) {
@ -10563,7 +10517,8 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter)
if (QDF_STATUS_SUCCESS != status) { if (QDF_STATUS_SUCCESS != status) {
hdd_err("Error Initializing the AP mode: %d", status); hdd_err("Error Initializing the AP mode: %d", status);
return qdf_status_to_os_return(status); ret = qdf_status_to_os_return(status);
goto sap_release_ref;
} }
hdd_register_tx_flow_control(adapter, hdd_register_tx_flow_control(adapter,
@ -10576,6 +10531,14 @@ int hdd_start_ap_adapter(struct hdd_adapter *adapter)
hdd_exit(); hdd_exit();
return 0; return 0;
sap_release_ref:
sap_release_vdev_ref(WLAN_HDD_GET_SAP_CTX_PTR(adapter));
sap_vdev_destroy:
hdd_vdev_destroy(adapter);
sap_destroy_ctx:
hdd_sap_destroy_ctx(adapter);
return ret;
} }
#if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL) #if defined(QCA_LL_TX_FLOW_CONTROL_V2) || defined(QCA_LL_PDEV_TX_FLOW_CONTROL)

View File

@ -1472,6 +1472,29 @@ wlansap_get_safe_channel_from_pcl_and_acs_range(struct sap_context *sap_ctx);
*/ */
qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx); qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx);
/**
* sap_acquire_vdev_ref() - Increment reference count for vdev object
* @psoc: Object Manager PSoC object
* @sap_ctx: to store vdev object pointer
* @session_id: used to get vdev object
*
* This function is used to increment vdev object reference count and store
* vdev pointer in sap_ctx.
*
* Return: QDF_STATUS_SUCCESS - If able to get vdev object reference
* else qdf status failure codes
*/
QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc,
struct sap_context *sap_ctx,
uint8_t session_id);
/**
* sap_release_vdev_ref() - Decrement reference count for vdev object
* @sap_ctx: for which vdev reference is to be decremented
*
* Return: None
*/
void sap_release_vdev_ref(struct sap_context *sap_ctx);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1083,7 +1083,7 @@ static QDF_STATUS sap_clear_global_dfs_param(mac_handle_t mac_handle)
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac, QDF_STATUS sap_acquire_vdev_ref(struct wlan_objmgr_psoc *psoc,
struct sap_context *sap_ctx, struct sap_context *sap_ctx,
uint8_t session_id) uint8_t session_id)
{ {
@ -1095,8 +1095,7 @@ QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac,
return QDF_STATUS_E_FAULT; return QDF_STATUS_E_FAULT;
} }
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, session_id,
session_id,
WLAN_LEGACY_SAP_ID); WLAN_LEGACY_SAP_ID);
if (!vdev) { if (!vdev) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH,
@ -1112,10 +1111,16 @@ void sap_release_vdev_ref(struct sap_context *sap_ctx)
{ {
struct wlan_objmgr_vdev *vdev; struct wlan_objmgr_vdev *vdev;
if (!sap_ctx) {
sap_err("Invalid SAP pointer");
return;
}
vdev = sap_ctx->vdev; vdev = sap_ctx->vdev;
sap_ctx->vdev = NULL; if (vdev) {
if (vdev) sap_ctx->vdev = NULL;
wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SAP_ID);
}
} }
QDF_STATUS sap_set_session_param(mac_handle_t mac_handle, QDF_STATUS sap_set_session_param(mac_handle_t mac_handle,
@ -1124,7 +1129,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle,
{ {
struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle); struct mac_context *mac_ctx = MAC_CONTEXT(mac_handle);
int i; int i;
QDF_STATUS status;
sapctx->sessionId = session_id; sapctx->sessionId = session_id;
sapctx->is_pre_cac_on = false; sapctx->is_pre_cac_on = false;
@ -1137,14 +1141,6 @@ QDF_STATUS sap_set_session_param(mac_handle_t mac_handle,
mac_ctx->sap.sapCtxList[i].sap_context = NULL; mac_ctx->sap.sapCtxList[i].sap_context = NULL;
} }
status = sap_acquire_vdev_ref(mac_ctx, sapctx, session_id);
if (!QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR,
FL("sap context init failed for session_id: %u"),
session_id);
return status;
}
mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx; mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = sapctx;
mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
sapctx->csr_roamProfile.csrPersona; sapctx->csr_roamProfile.csrPersona;
@ -1164,8 +1160,6 @@ QDF_STATUS sap_clear_session_param(mac_handle_t mac_handle,
if (sapctx->sessionId >= SAP_MAX_NUM_SESSION) if (sapctx->sessionId >= SAP_MAX_NUM_SESSION)
return QDF_STATUS_E_FAILURE; return QDF_STATUS_E_FAILURE;
sap_release_vdev_ref(sapctx);
mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL; mac_ctx->sap.sapCtxList[sapctx->sessionId].sap_context = NULL;
mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona = mac_ctx->sap.sapCtxList[sapctx->sessionId].sapPersona =
QDF_MAX_NO_OF_MODE; QDF_MAX_NO_OF_MODE;

View File

@ -479,29 +479,4 @@ bool
sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context, sap_chan_bond_dfs_sub_chan(struct sap_context *sap_context,
uint8_t channel_number, uint8_t channel_number,
ePhyChanBondState bond_state); ePhyChanBondState bond_state);
/**
* sap_acquire_vdev_ref() - Increment reference count for vdev object
* @mac: mac handle
* @sap_ctx: to store vdev object pointer
* @session_id: used to get vdev object
*
* This function is used to increment vdev object reference count and store
* vdev pointer in sap_ctx.
*
* Return: QDF_STATUS_SUCCESS - If able to get vdev object reference
* else qdf status failure codes
*/
QDF_STATUS sap_acquire_vdev_ref(struct mac_context *mac,
struct sap_context *sap_ctx,
uint8_t session_id);
/**
* sap_release_vdev_ref() - Decrement reference count for vdev object
* @sap_ctx: for which vdev reference is to be decremented
*
* Return: None
*/
void sap_release_vdev_ref(struct sap_context *sap_ctx);
#endif #endif

View File

@ -2669,18 +2669,6 @@ QDF_STATUS wma_post_vdev_start_setup(uint8_t vdev_id);
QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id, QDF_STATUS wma_pre_vdev_start_setup(uint8_t vdev_id,
struct bss_params *add_bss); struct bss_params *add_bss);
/**
* wma_release_pending_vdev_refs() - release vdev ref taken by interface txrx
* node and delete all the peers attached to this vdev.
*
* This API loop and release vdev ref taken by all iface and all the peers
* attached to the vdev, this need to be called on recovery to flush vdev
* and peer.
*
* Return: void.
*/
void wma_release_pending_vdev_refs(void);
#ifdef FEATURE_ANI_LEVEL_REQUEST #ifdef FEATURE_ANI_LEVEL_REQUEST
/** /**
* wma_send_ani_level_request() - Send get ani level cmd to WMI * wma_send_ani_level_request() - Send get ani level cmd to WMI

View File

@ -601,9 +601,6 @@ out:
wma_vdev_deinit(iface); wma_vdev_deinit(iface);
qdf_mem_zero(iface, sizeof(*iface)); qdf_mem_zero(iface, sizeof(*iface));
wma_vdev_init(iface); wma_vdev_init(iface);
del_vdev_req_param->status = status;
wma_send_vdev_del_resp(del_vdev_req_param);
return status; return status;
} }
@ -679,95 +676,6 @@ error:
return qdf_status; return qdf_status;
} }
/**
* wma_force_objmgr_vdev_peer_cleanup() - Cleanup ObjMgr Vdev peers during SSR
* @wma_handle: WMA handle
* @iface: wma interface txrx node
*
* Return: none
*/
static void wma_force_objmgr_vdev_peer_cleanup(tp_wma_handle wma,
struct wma_txrx_node *iface)
{
struct wlan_objmgr_vdev *vdev;
struct wlan_objmgr_peer *peer = NULL;
struct wlan_objmgr_peer *peer_next = NULL;
qdf_list_t *peer_list;
void *soc = cds_get_context(QDF_MODULE_ID_SOC);
if (!iface->vdev)
return;
/*
* No need to take ref as if iface->vdev is valid then WMA already hold
* ref and this can be used diretly. ALso this API may get called after
* vdev deleted logically so taking ref for vdev will fail and peer
* wont be deleted for the vdev.
*/
vdev = iface->vdev;
wma_cdp_vdev_detach(soc, wma, wlan_vdev_get_id(vdev));
WMA_LOGI("%s: SSR: force cleanup peers in vdev(%d)", __func__,
wlan_vdev_get_id(vdev));
iface->vdev_active = false;
peer_list = &vdev->vdev_objmgr.wlan_peer_list;
if (!peer_list) {
WMA_LOGE("%s: peer_list is NULL", __func__);
return;
}
/*
* We get refcount for each peer first, logically delete it and
* then release the refcount so that the peer is physically
* deleted.
*/
peer = wlan_vdev_peer_list_peek_active_head(vdev, peer_list,
WLAN_LEGACY_WMA_ID);
while (peer) {
WMA_LOGD("%s: Deleting Peer %pM",
__func__, peer->macaddr);
wlan_objmgr_peer_obj_delete(peer);
peer_next = wlan_peer_get_next_active_peer_of_vdev(vdev,
peer_list, peer, WLAN_LEGACY_WMA_ID);
wlan_objmgr_peer_release_ref(peer, WLAN_LEGACY_WMA_ID);
peer = peer_next;
}
/* Force delete all the peers, set the wma interface peer_count to 0 */
iface->peer_count = 0;
}
static void
wma_release_vdev_and_peer_ref(tp_wma_handle wma,
struct wma_txrx_node *iface)
{
if (!iface) {
WMA_LOGE("iface is NULL");
return;
}
wma_force_objmgr_vdev_peer_cleanup(wma, iface);
wma_release_vdev_ref(iface);
}
void wma_release_pending_vdev_refs(void)
{
int i;
tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA);
/* validate the wma_handle */
if (!wma) {
WMA_LOGE("%s: Invalid wma handle", __func__);
return;
}
for (i = 0; i < wma->max_bssid; i++)
/* Release peer and vdev ref hold by wma if not already done */
wma_release_vdev_and_peer_ref(wma, &wma->interfaces[i]);
}
static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype) static bool wma_vdev_uses_self_peer(uint32_t vdev_type, uint32_t vdev_subtype)
{ {
switch (vdev_type) { switch (vdev_type) {
@ -908,18 +816,6 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
goto send_rsp; goto send_rsp;
} }
/*
* In SSR case or if FW is down we only need to clean up the host.
* There is no need to destroy vdev in firmware since it
* has already asserted.
* Cleanup the ObjMgr Peers for the current vdev and detach the
* CDP Vdev.
*/
if (!cds_is_target_ready()) {
wma_release_vdev_and_peer_ref(wma_handle, iface);
goto send_rsp;
}
status = wma_check_for_deffered_peer_delete(wma_handle, status = wma_check_for_deffered_peer_delete(wma_handle,
pdel_vdev_req_param); pdel_vdev_req_param);
if (QDF_IS_STATUS_ERROR(status)) if (QDF_IS_STATUS_ERROR(status))
@ -934,7 +830,7 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
if (QDF_IS_STATUS_ERROR(status)) { if (QDF_IS_STATUS_ERROR(status)) {
wma_err("Failed to send self peer delete:%d", status); wma_err("Failed to send self peer delete:%d", status);
return status; goto send_rsp;
} }
if (iface->type != WMI_VDEV_TYPE_MONITOR) if (iface->type != WMI_VDEV_TYPE_MONITOR)
@ -947,6 +843,9 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
pdel_vdev_req_param); pdel_vdev_req_param);
} }
if (QDF_IS_STATUS_ERROR(status))
goto send_rsp;
return status; return status;
send_fail_rsp: send_fail_rsp:
@ -5254,6 +5153,7 @@ void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id)
if (wma_send_vdev_stop_to_fw(wma, vdev_id)) { if (wma_send_vdev_stop_to_fw(wma, vdev_id)) {
WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__); WMA_LOGE("%s: %d Failed to send vdev stop", __func__, __LINE__);
status = QDF_STATUS_E_FAILURE; status = QDF_STATUS_E_FAILURE;
qdf_atomic_set(&iface->bss_status, WMA_BSS_STATUS_STOPPED);
goto detach_peer; goto detach_peer;
} }
WMA_LOGD("%s: bssid %pM vdev_id %d", WMA_LOGD("%s: bssid %pM vdev_id %d",

View File

@ -2618,11 +2618,6 @@ void wma_vdev_deinit(struct wma_txrx_node *vdev)
vdev->staKeyParams = NULL; vdev->staKeyParams = NULL;
} }
if (vdev->del_staself_req) {
qdf_mem_free(vdev->del_staself_req);
vdev->del_staself_req = NULL;
}
if (vdev->psnr_req) { if (vdev->psnr_req) {
qdf_mem_free(vdev->psnr_req); qdf_mem_free(vdev->psnr_req);
vdev->psnr_req = NULL; vdev->psnr_req = NULL;
@ -4303,7 +4298,7 @@ QDF_STATUS wma_wmi_service_close(void)
{ {
void *cds_ctx; void *cds_ctx;
tp_wma_handle wma_handle; tp_wma_handle wma_handle;
int i; uint8_t i;
WMA_LOGD("%s: Enter", __func__); WMA_LOGD("%s: Enter", __func__);