diff --git a/drivers/staging/qcacld-3.0/Kbuild b/drivers/staging/qcacld-3.0/Kbuild index c01c511cd69f..f94c7c871e88 100644 --- a/drivers/staging/qcacld-3.0/Kbuild +++ b/drivers/staging/qcacld-3.0/Kbuild @@ -425,6 +425,7 @@ HDD_OBJS := $(HDD_SRC_DIR)/wlan_hdd_assoc.o \ $(HDD_SRC_DIR)/wlan_hdd_packet_filter.o \ $(HDD_SRC_DIR)/wlan_hdd_power.o \ $(HDD_SRC_DIR)/wlan_hdd_regulatory.o \ + $(HDD_SRC_DIR)/wlan_hdd_request_manager.o \ $(HDD_SRC_DIR)/wlan_hdd_scan.o \ $(HDD_SRC_DIR)/wlan_hdd_softap_tx_rx.o \ $(HDD_SRC_DIR)/wlan_hdd_tx_rx.o \ diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c index 2c240a7ab962..4ff620ddb07b 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_api.c @@ -131,6 +131,7 @@ v_CONTEXT_t cds_init(void) qdf_lock_stats_init(); qdf_mem_init(); qdf_mc_timer_manager_init(); + qdf_event_list_init(); gp_cds_context = &g_cds_context; @@ -166,6 +167,7 @@ void cds_deinit(void) qdf_mem_exit(); qdf_lock_stats_deinit(); qdf_debugfs_exit(); + qdf_event_list_destroy(); gp_cds_context->qdf_ctx = NULL; gp_cds_context = NULL; @@ -626,8 +628,9 @@ QDF_STATUS cds_pre_enable(v_CONTEXT_t cds_context) } /* Need to update time out of complete */ - qdf_status = qdf_wait_single_event(&gp_cds_context->wmaCompleteEvent, - CDS_WMA_TIMEOUT); + qdf_status = qdf_wait_for_event_completion( + &gp_cds_context->wmaCompleteEvent, + CDS_WMA_TIMEOUT); if (qdf_status != QDF_STATUS_SUCCESS) { if (qdf_status == QDF_STATUS_E_TIMEOUT) { QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, @@ -781,8 +784,9 @@ QDF_STATUS cds_enable(v_CONTEXT_t cds_context) wma_setneedshutdown(cds_context); } else { qdf_status = - qdf_wait_single_event(&(gp_cds_context->wmaCompleteEvent), - CDS_WMA_TIMEOUT); + qdf_wait_for_event_completion( + &gp_cds_context->wmaCompleteEvent, + CDS_WMA_TIMEOUT); if (qdf_status != QDF_STATUS_SUCCESS) { if (qdf_status == QDF_STATUS_E_TIMEOUT) { QDF_TRACE(QDF_MODULE_ID_QDF, @@ -1814,7 +1818,7 @@ static QDF_STATUS cds_force_assert_target(qdf_device_t qdf_ctx) } /* wait for firmware assert to trigger a recovery event */ - status = qdf_wait_single_event(&wma->recovery_event, + status = qdf_wait_for_event_completion(&wma->recovery_event, WMA_CRASH_INJECT_TIMEOUT); if (QDF_IS_STATUS_ERROR(status)) { cds_err("Failed target force assert wait; status:%d", status); diff --git a/drivers/staging/qcacld-3.0/core/cds/src/cds_concurrency.c b/drivers/staging/qcacld-3.0/core/cds/src/cds_concurrency.c index b560ddd3f3bf..a1dffae02554 100644 --- a/drivers/staging/qcacld-3.0/core/cds/src/cds_concurrency.c +++ b/drivers/staging/qcacld-3.0/core/cds/src/cds_concurrency.c @@ -8503,7 +8503,7 @@ void cds_restart_sap(hdd_adapter_t *ap_adapter) qdf_event_reset(&hostapd_state->qdf_stop_bss_event); if (QDF_STATUS_SUCCESS == wlansap_stop_bss(sap_ctx)) { qdf_status = - qdf_wait_single_event(&hostapd_state-> + qdf_wait_for_event_completion(&hostapd_state-> qdf_stop_bss_event, SME_CMD_TIMEOUT_VALUE); @@ -8536,7 +8536,7 @@ void cds_restart_sap(hdd_adapter_t *ap_adapter) cds_debug("Waiting for SAP to start"); qdf_status = - qdf_wait_single_event(&hostapd_state->qdf_event, + qdf_wait_for_event_completion(&hostapd_state->qdf_event, SME_CMD_TIMEOUT_VALUE); wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL); @@ -8968,7 +8968,7 @@ QDF_STATUS qdf_wait_for_connection_update(void) return QDF_STATUS_E_FAILURE; } - status = qdf_wait_single_event( + status = qdf_wait_for_event_completion( &cds_context->connection_update_done_evt, CONNECTION_UPDATE_TIMEOUT); diff --git a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c index 2d51d5f78b0c..2d5c418c0f02 100644 --- a/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c +++ b/drivers/staging/qcacld-3.0/core/dp/txrx/ol_txrx.c @@ -2538,7 +2538,7 @@ ol_txrx_peer_attach(ol_txrx_vdev_handle vdev, uint8_t *peer_mac_addr) sizeof(union ol_txrx_align_mac_addr_t)); if (wait_on_deletion) { /* wait for peer deletion */ - rc = qdf_wait_single_event(&vdev->wait_delete_comp, + rc = qdf_wait_for_event_completion(&vdev->wait_delete_comp, PEER_DELETION_TIMEOUT); if (QDF_STATUS_SUCCESS != rc) { ol_txrx_err( diff --git a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h index 80053e9ff463..5d0e51e59fdc 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h +++ b/drivers/staging/qcacld-3.0/core/hdd/inc/wlan_hdd_cfg.h @@ -2146,6 +2146,53 @@ enum hdd_dot11_mode { #define CFG_ROAM_BG_SCAN_CLIENT_BITMAP_MAX (0x7FF) #define CFG_ROAM_BG_SCAN_CLIENT_BITMAP_DEFAULT (0x424) +/* + * + * min_delay_btw_roam_scans - Min duration (in sec) allowed btw two + * consecutive roam scans + * @Min: 0 + * @Max: 60 + * @Default: 10 + * + * Roam scan is not allowed if duration between two consecutive + * roam scans is less than this time. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_MIN_DELAY_BTW_ROAM_SCAN_NAME "min_delay_btw_roam_scans" +#define CFG_MIN_DELAY_BTW_ROAM_SCAN_MIN (0) +#define CFG_MIN_DELAY_BTW_ROAM_SCAN_MAX (60) +#define CFG_MIN_DELAY_BTW_ROAM_SCAN_DEFAULT (10) + +/* + * + * roam_trigger_reason_bitmask - Contains roam_trigger_reasons + * @Min: 0 + * @Max: 0xFFFFFFFF + * @Default: 0xDA + * + * Bitmask containing roam_trigger_reasons for which + * min_delay_btw_roam_scans constraint should be applied. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_NAME "roam_trigger_reason_bitmask" +#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MIN (0) +#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MAX (0xFFFFFFFF) +#define CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_DEFAULT (0xDA) + /* * * roam_bad_rssi_thresh_offset_2g - RSSI threshold offset for 2G to 5G roam @@ -2176,6 +2223,56 @@ enum hdd_dot11_mode { #define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MAX (86) #define CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_DEFAULT (40) +/* + * + * ho_delay_for_rx - Delay Hand-off (In msec) by this duration to receive + * pending rx frames from current BSS + * @Min: 0 + * @Max: 200 + * @Default: 0 + * + * For LFR 3.0 roaming scenario, once roam candidate is found, firmware + * waits for minimum this much duration to receive pending rx frames from + * current BSS before switching to new channel for handoff to new AP. + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_ROAM_HO_DELAY_FOR_RX_NAME "ho_delay_for_rx" +#define CFG_ROAM_HO_DELAY_FOR_RX_MIN (0) +#define CFG_ROAM_HO_DELAY_FOR_RX_MAX (200) +#define CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT (0) + +/* + * + * roam_force_rssi_trigger - To set roam scan mode + * irrespective of channel list + * @Min: 0 + * @Max: 1 + * @Default: 1 + * + * This ini is used to set roam scan mode + * WMI_ROAM_SCAN_MODE_RSSI_CHANGE, irrespective of whether + * channel list type is CHANNEL_LIST_STATIC or not + * + * Related: None + * + * Supported Feature: Roaming + * + * Usage: External + * + * + */ +#define CFG_ROAM_FORCE_RSSI_TRIGGER_NAME "roam_force_rssi_trigger" +#define CFG_ROAM_FORCE_RSSI_TRIGGER_MIN (0) +#define CFG_ROAM_FORCE_RSSI_TRIGGER_MAX (1) +#define CFG_ROAM_FORCE_RSSI_TRIGGER_DEFAULT (1) + /* * * roamscan_adaptive_dwell_mode - Sets dwell time adaptive mode @@ -13876,6 +13973,9 @@ struct hdd_config { uint32_t roam_dense_min_aps; int8_t roam_bg_scan_bad_rssi_thresh; uint8_t roam_bad_rssi_thresh_offset_2g; + uint32_t ho_delay_for_rx; + uint32_t min_delay_btw_roam_scans; + uint32_t roam_trigger_reason_bitmask; uint32_t roam_bg_scan_client_bitmap; bool enable_edca_params; uint32_t edca_vo_cwmin; @@ -14078,6 +14178,7 @@ struct hdd_config { uint32_t neighbor_report_offload_cache_timeout; uint32_t neighbor_report_offload_max_req_cap; uint8_t enable_tx_sch_delay; + bool roam_force_rssi_trigger; }; #define VAR_OFFSET(_Struct, _Var) (offsetof(_Struct, _Var)) diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c index 043b917cfd73..320b251f379f 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg.c @@ -4043,6 +4043,30 @@ struct reg_table_entry g_registry_table[] = { CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MIN, CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_MAX), + REG_VARIABLE(CFG_ROAM_HO_DELAY_FOR_RX_NAME, + WLAN_PARAM_Integer, struct hdd_config, + ho_delay_for_rx, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_HO_DELAY_FOR_RX_DEFAULT, + CFG_ROAM_HO_DELAY_FOR_RX_MIN, + CFG_ROAM_HO_DELAY_FOR_RX_MAX), + + REG_VARIABLE(CFG_MIN_DELAY_BTW_ROAM_SCAN_NAME, + WLAN_PARAM_Integer, struct hdd_config, + min_delay_btw_roam_scans, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_MIN_DELAY_BTW_ROAM_SCAN_DEFAULT, + CFG_MIN_DELAY_BTW_ROAM_SCAN_MIN, + CFG_MIN_DELAY_BTW_ROAM_SCAN_MAX), + + REG_VARIABLE(CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_NAME, + WLAN_PARAM_HexInteger, struct hdd_config, + roam_trigger_reason_bitmask, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_DEFAULT, + CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MIN, + CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_MAX), + REG_VARIABLE(CFG_ENABLE_FATAL_EVENT_TRIGGER, WLAN_PARAM_Integer, struct hdd_config, enable_fatal_event, VAR_FLAGS_OPTIONAL | @@ -5271,6 +5295,15 @@ struct reg_table_entry g_registry_table[] = { CFG_TX_SCH_DELAY_DEFAULT, CFG_TX_SCH_DELAY_MIN, CFG_TX_SCH_DELAY_MAX), + + REG_VARIABLE(CFG_ROAM_FORCE_RSSI_TRIGGER_NAME, + WLAN_PARAM_Integer, struct hdd_config, + roam_force_rssi_trigger, + VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_ROAM_FORCE_RSSI_TRIGGER_DEFAULT, + CFG_ROAM_FORCE_RSSI_TRIGGER_MIN, + CFG_ROAM_FORCE_RSSI_TRIGGER_MAX), + }; /** @@ -6753,6 +6786,15 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) hdd_debug("Name = [%s] Value = [%u]", CFG_ROAM_BG_SCAN_BAD_RSSI_OFFSET_2G_NAME, pHddCtx->config->roam_bad_rssi_thresh_offset_2g); + hdd_debug("Name = [%s] Value = [%u]", + CFG_ROAM_HO_DELAY_FOR_RX_NAME, + pHddCtx->config->ho_delay_for_rx); + hdd_debug("Name = [%s] Value = [%u]", + CFG_MIN_DELAY_BTW_ROAM_SCAN_NAME, + pHddCtx->config->min_delay_btw_roam_scans); + hdd_debug("Name = [%s] Value = [%u]", + CFG_ROAM_SCAN_TRIGGER_REASON_BITMASK_NAME, + pHddCtx->config->roam_trigger_reason_bitmask); hdd_debug("Name = [%s] Value = [%u]", CFG_MIN_REST_TIME_NAME, pHddCtx->config->min_rest_time_conc); @@ -7068,6 +7110,10 @@ void hdd_cfg_print(hdd_context_t *pHddCtx) pHddCtx->config->enable_tx_sch_delay); hdd_cfg_print_11k_offload_params(pHddCtx); + hdd_debug("Name = [%s] Value = [%u]", + CFG_ROAM_FORCE_RSSI_TRIGGER_NAME, + pHddCtx->config->roam_force_rssi_trigger); + } /** @@ -9546,6 +9592,12 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) pHddCtx->config->roam_bg_scan_client_bitmap; smeConfig->csrConfig.roam_bad_rssi_thresh_offset_2g = pHddCtx->config->roam_bad_rssi_thresh_offset_2g; + smeConfig->csrConfig.ho_delay_for_rx = + pHddCtx->config->ho_delay_for_rx; + smeConfig->csrConfig.min_delay_btw_roam_scans = + pHddCtx->config->min_delay_btw_roam_scans; + smeConfig->csrConfig.roam_trigger_reason_bitmask = + pHddCtx->config->roam_trigger_reason_bitmask; smeConfig->csrConfig.obss_width_interval = pHddCtx->config->obss_width_trigger_interval; smeConfig->csrConfig.obss_active_dwelltime = @@ -9560,6 +9612,8 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx) pHddCtx->config->scan_adaptive_dwell_mode; smeConfig->csrConfig.roamscan_adaptive_dwell_mode = pHddCtx->config->roamscan_adaptive_dwell_mode; + smeConfig->csrConfig.roam_force_rssi_trigger = + pHddCtx->config->roam_force_rssi_trigger; hdd_update_per_config_to_sme(pHddCtx, smeConfig); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c index 813a7eeffd0f..a30cce86d9d7 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_cfg80211.c @@ -15928,7 +15928,7 @@ static bool wlan_hdd_handle_sap_sta_dfs_conc(hdd_adapter_t *adapter, * machine from disconnected to started and set this event. * wait for 10 secs to finish this. */ - status = qdf_wait_single_event(&hostapd_state->qdf_event, 10000); + status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, 10000); if (!QDF_IS_STATUS_SUCCESS(status)) { hdd_err("wait for qdf_event failed, STA not allowed!!"); return false; @@ -18679,7 +18679,7 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, pAdapter->aStaInfo[i]. isDeauthInProgress = true; qdf_status = - qdf_wait_single_event( + qdf_wait_for_event_completion( &hapd_state-> qdf_sta_disassoc_event, SME_CMD_TIMEOUT_VALUE); @@ -18744,10 +18744,10 @@ int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy, MAC_ADDR_ARRAY(mac)); return -ENOENT; } else { - qdf_status = qdf_wait_single_event( - &hapd_state-> - qdf_sta_disassoc_event, - SME_CMD_TIMEOUT_VALUE); + qdf_status = qdf_wait_for_event_completion( + &hapd_state-> + qdf_sta_disassoc_event, + SME_CMD_TIMEOUT_VALUE); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) hdd_warn("Deauth wait time expired"); } diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c index 5624731d91b2..0b4079aa0e9d 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_driver_ops.c @@ -1294,6 +1294,7 @@ static void hdd_cleanup_on_fw_down(void) ENTER(); hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + qdf_complete_wait_events(); cds_set_target_ready(false); if (hdd_ctx != NULL) hdd_cleanup_scan_queue(hdd_ctx, NULL); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c index eabc11098f9f..4621651ad6e6 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_hostapd.c @@ -5353,7 +5353,7 @@ __iw_softap_stopbss(struct net_device *dev, WLAN_HDD_GET_SAP_CTX_PTR(pHostapdAdapter)); if (QDF_IS_STATUS_SUCCESS(status)) { qdf_status = - qdf_wait_single_event(&pHostapdState-> + qdf_wait_for_event_completion(&pHostapdState-> qdf_stop_bss_event, SME_CMD_TIMEOUT_VALUE); @@ -8665,7 +8665,7 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, hdd_debug("Waiting for Scan to complete(auto mode) and BSS to start"); - qdf_status = qdf_wait_single_event(&pHostapdState->qdf_event, + qdf_status = qdf_wait_for_event_completion(&pHostapdState->qdf_event, SME_CMD_TIMEOUT_VALUE); wlansap_reset_sap_config_add_ie(pConfig, eUPDATE_IE_ALL); @@ -8891,7 +8891,7 @@ static int __wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy, status = wlansap_stop_bss(WLAN_HDD_GET_SAP_CTX_PTR(pAdapter)); if (QDF_IS_STATUS_SUCCESS(status)) { qdf_status = - qdf_wait_single_event(&pHostapdState-> + qdf_wait_for_event_completion(&pHostapdState-> qdf_stop_bss_event, SME_CMD_TIMEOUT_VALUE); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c index 092afd6e4de3..95a7c948e5c8 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_main.c @@ -54,6 +54,7 @@ #include "wlan_hdd_power.h" #include "wlan_hdd_stats.h" #include "wlan_hdd_scan.h" +#include "wlan_hdd_request_manager.h" #include "qdf_types.h" #include "qdf_trace.h" #include @@ -4206,8 +4207,8 @@ QDF_STATUS hdd_stop_adapter(hdd_context_t *hdd_ctx, hdd_adapter_t *adapter, qdf_event_reset(&hostapd_state-> qdf_stop_bss_event); qdf_status = - qdf_wait_single_event(&hostapd_state-> - qdf_stop_bss_event, + qdf_wait_for_event_completion( + &hostapd_state->qdf_stop_bss_event, SME_CMD_TIMEOUT_VALUE); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { @@ -5915,6 +5916,7 @@ static void hdd_wlan_exit(hdd_context_t *hdd_ctx) */ hdd_green_ap_deinit(hdd_ctx); + hdd_request_manager_deinit(); hdd_runtime_suspend_context_deinit(hdd_ctx); hdd_close_all_adapters(hdd_ctx, false); @@ -9953,6 +9955,7 @@ int hdd_wlan_startup(struct device *dev) if (QDF_IS_STATUS_ERROR(ret)) goto err_hdd_free_context; + hdd_request_manager_init(); hdd_green_ap_init(hdd_ctx); hdd_init_spectral_scan(hdd_ctx); @@ -10076,6 +10079,7 @@ int hdd_wlan_startup(struct device *dev) } hdd_green_ap_deinit(hdd_ctx); + hdd_request_manager_deinit(); hdd_exit_netlink_services(hdd_ctx); cds_deinit_ini_config(); @@ -10963,8 +10967,8 @@ void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter) qdf_event_reset(&hostapd_state->qdf_stop_bss_event); if (QDF_STATUS_SUCCESS == wlansap_stop_bss(hdd_ap_ctx-> sapContext)) { - qdf_status = qdf_wait_single_event(&hostapd_state-> - qdf_stop_bss_event, + qdf_status = qdf_wait_for_event_completion( + &hostapd_state->qdf_stop_bss_event, SME_CMD_TIMEOUT_VALUE); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { mutex_unlock(&hdd_ctx->sap_lock); @@ -11030,7 +11034,7 @@ void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter, bool reinit) goto end; hdd_debug("Waiting for SAP to start"); - qdf_status = qdf_wait_single_event(&hostapd_state->qdf_event, + qdf_status = qdf_wait_for_event_completion(&hostapd_state->qdf_event, SME_CMD_TIMEOUT_VALUE); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("SAP Start failed"); diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.c new file mode 100644 index 000000000000..a90b928e8c9d --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include "wlan_hdd_request_manager.h" +#include "wlan_hdd_main.h" +#include "qdf_list.h" +#include "qdf_event.h" +#include "qdf_mem.h" + +/* arbitrary value */ +#define MAX_NUM_REQUESTS 20 + +static bool is_initialized; +static qdf_list_t requests; +static qdf_spinlock_t spinlock; +static void *cookie; + +struct hdd_request { + qdf_list_node_t node; + void *cookie; + uint32_t reference_count; + struct hdd_request_params params; + qdf_event_t completed; +}; + +/* must be called with spinlock held */ +static void hdd_request_unlink(struct hdd_request *request) +{ + qdf_list_remove_node(&requests, &request->node); +} + +static void hdd_request_destroy(struct hdd_request *request) +{ + struct hdd_request_params *params; + + params = &request->params; + if (params->dealloc) { + void *priv = hdd_request_priv(request); + + params->dealloc(priv); + } + qdf_event_destroy(&request->completed); + qdf_mem_free(request); +} + +/* must be called with spinlock held */ +static struct hdd_request *hdd_request_find(void *cookie) +{ + QDF_STATUS status; + struct hdd_request *request; + qdf_list_node_t *node; + + status = qdf_list_peek_front(&requests, &node); + while (QDF_IS_STATUS_SUCCESS(status)) { + request = qdf_container_of(node, struct hdd_request, node); + if (request->cookie == cookie) + return request; + status = qdf_list_peek_next(&requests, node, &node); + } + + return NULL; +} + +struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params) +{ + size_t length; + struct hdd_request *request; + + if (!is_initialized) { + hdd_err("invoked when not initialized from %pS", + (void *)_RET_IP_); + return NULL; + } + + length = sizeof(*request) + params->priv_size; + request = qdf_mem_malloc(length); + if (!request) { + hdd_err("allocation failed for %pS", (void *)_RET_IP_); + return NULL; + } + request->reference_count = 1; + request->params = *params; + qdf_event_create(&request->completed); + qdf_spin_lock_bh(&spinlock); + request->cookie = cookie++; + qdf_list_insert_back(&requests, &request->node); + qdf_spin_unlock_bh(&spinlock); + hdd_debug("request %pK, cookie %pK, caller %pS", + request, request->cookie, (void *)_RET_IP_); + + return request; +} + +void *hdd_request_priv(struct hdd_request *request) +{ + /* private data area immediately follows the struct hdd_request */ + return request + 1; +} + +void *hdd_request_cookie(struct hdd_request *request) +{ + return request->cookie; +} + +struct hdd_request *hdd_request_get(void *cookie) +{ + struct hdd_request *request; + + if (!is_initialized) { + hdd_err("invoked when not initialized from %pS", + (void *)_RET_IP_); + return NULL; + } + qdf_spin_lock_bh(&spinlock); + request = hdd_request_find(cookie); + if (request) + request->reference_count++; + qdf_spin_unlock_bh(&spinlock); + hdd_debug("cookie %pK, request %pK, caller %pS", + cookie, request, (void *)_RET_IP_); + + return request; +} + +void hdd_request_put(struct hdd_request *request) +{ + bool unlinked = false; + + hdd_debug("request %pK, cookie %pK, caller %pS", + request, request->cookie, (void *)_RET_IP_); + qdf_spin_lock_bh(&spinlock); + request->reference_count--; + if (0 == request->reference_count) { + hdd_request_unlink(request); + unlinked = true; + } + qdf_spin_unlock_bh(&spinlock); + if (unlinked) + hdd_request_destroy(request); +} + +int hdd_request_wait_for_response(struct hdd_request *request) +{ + QDF_STATUS status; + + status = qdf_wait_for_event_completion(&request->completed, + request->params.timeout_ms); + + return qdf_status_to_os_return(status); +} + +void hdd_request_complete(struct hdd_request *request) +{ + (void) qdf_event_set(&request->completed); +} + +void hdd_request_manager_init(void) +{ + hdd_debug("%pS", (void *)_RET_IP_); + if (is_initialized) + return; + + qdf_list_create(&requests, MAX_NUM_REQUESTS); + qdf_spinlock_create(&spinlock); + is_initialized = true; +} + +/* + * hdd_request_manager_deinit implementation note: + * It is intentional that we do not destroy the list or the spinlock. + * This allows threads to still access the infrastructure even when it + * has been deinitialized. Since neither lists nor spinlocks consume + * resources this does not result in a resource leak. + */ +void hdd_request_manager_deinit(void) +{ + hdd_debug("%pS", (void *)_RET_IP_); + is_initialized = false; +} diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.h b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.h new file mode 100644 index 000000000000..357ef2a12d69 --- /dev/null +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_request_manager.h @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved. + * + * Permission to use, copy, modify, and/or distribute this software for + * any purpose with or without fee is hereby granted, provided that the + * above copyright notice and this permission notice appear in all + * copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE + * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef __WLAN_HDD_REQUEST_MANAGER_H__ +#define __WLAN_HDD_REQUEST_MANAGER_H__ + +/** + * DOC: WLAN HDD REQUEST MANAGER + * + * Many operations within the wlan driver occur in an asynchronous + * manner. Requests are received by HDD via one of the kernel + * interfaces (ioctl, nl80211, virtual file system, etc.). The + * requests are translated to an internal format and are then passed + * to lower layers, usually via SME, for processing. For requests + * which require a response, that response comes up from the lower + * layers in a separate thread of execution, ultimately resulting in a + * call to a callback function that was provided by HDD as part of the + * initial request. So a mechanism is needed to synchronize the + * request and response. This framework provides that mechanism. + * + * Once the framework has been initialized, the typical sequence of + * events is as follows: + * + * Request Thread: + * 1. Create a &struct hdd_request_params which describes the request. + * 2. Call hdd_request_alloc() to allocate a &struct hdd_request. + * 3. Call hdd_request_priv() to get a pointer to the private data. + * 4. Place any information which must be shared with the Response + * Callback in the private data area. + * 5. Call hdd_request_cookie() to get the unique cookie assigned + * to the request. + * 6. Call the underlying request handling API, passing the cookie + * as the callback's private context. + * 7. Call hdd_request_wait_for_response() to wait for the response + * (or for the request to time out). + * 8. Use the return status to see if the request was successful. If + * it was, retrieve any response information from the private + * structure and prepare a response for userspace. + * 9. Call hdd_request_put() to relinquish access to the request. + * 10. Return status to the caller. + * + * Response Callback: + * 1. Call hdd_request_get() with the provided cookie to see if the + * request structure is still valid. If it returns %NULL then + * return since this means the request thread has already timed + * out. + * 2. Call hdd_request_priv() to get access to the private data area. + * 3. Write response data into the private data area. + * 4. Call hdd_request_complete() to indicate that the response is + * ready to be processed by the request thread. + * 5. Call hdd_request_put() to relinquish the callback function's + * reference to the request. + */ + +/* this is opaque to clients */ +struct hdd_request; + +/** + * typedef hdd_request_dealloc - Private data deallocation function + */ +typedef void (*hdd_request_dealloc)(void *priv); + +/** + * struct hdd_request_params - HDD request parameters + * @priv_size: Size of the private data area required to pass + * information between the request thread and the response callback. + * @timeout_ms: The amount of time to wait for a response in milliseconds. + * @dealloc: Function to be called when the request is destroyed to + * deallocate any allocations made in the private area of the + * request struct. Can be %NULL if no private allocations are + * made. + */ +struct hdd_request_params { + uint32_t priv_size; + uint32_t timeout_ms; + hdd_request_dealloc dealloc; +}; + +/** + * hdd_request_alloc() - Allocate a request struct + * @params: parameter block that specifies the attributes of the + * request + * + * This function will attempt to allocate a &struct hdd_request with + * the specified @params. If successful, the caller can then use + * request struct to make an asynchronous request. Once the request is + * no longer needed, the reference should be relinquished via a call + * to hdd_request_put(). + * + * Return: A pointer to an allocated &struct hdd_request (which also + * contains room for the private buffer) if the allocation is + * successful, %NULL if the allocation fails. + */ +struct hdd_request *hdd_request_alloc(const struct hdd_request_params *params); + +/** + * hdd_request_priv() - Get pointer to request private data + * @request: The request struct that contains the private data + * + * This function will return a pointer to the private data area that + * is part of the request struct. The caller must already have a valid + * reference to @request from either hdd_request_alloc() or + * hdd_request_get(). + * + * Returns: pointer to the private data area. Note that this pointer + * will always be an offset from the input @request pointer and hence + * this function will never return %NULL. + */ +void *hdd_request_priv(struct hdd_request *request); + +/** + * hdd_request_cookie() - Get cookie of a request + * @request: The request struct associated with the request + * + * This function will return the unique cookie that has been assigned + * to the request. This cookie can subsequently be passed to + * hdd_request_get() to retrieve the request. + * + * Note that the cookie is defined as a void pointer as it is intended + * to be passed as an opaque context pointer from HDD to underlying + * layers when making a request, and subsequently passed back to HDD + * as an opaque pointer in an asynchronous callback. + * + * Returns: The cookie assigned to the request. + */ +void *hdd_request_cookie(struct hdd_request *request); + +/** + * hdd_request_get() - Get a reference to a request struct + * @cookie: The cookie of the request struct that needs to be + * referenced + * + * This function will use the cookie to determine if the associated + * request struct is valid, and if so, will increment the reference + * count of the struct. This means the caller is guaranteed that the + * request struct is valid and the underlying private data can be + * dereferenced. + * + * Returns: The pointer to the request struct associated with @cookie + * if the request is still valid, %NULL if the underlying request + * struct is no longer valid. + */ +struct hdd_request *hdd_request_get(void *cookie); + +/** + * hdd_request_put() - Release a reference to a request struct + * @request: The request struct that no longer needs to be referenced + * + * This function will decrement the reference count of the struct, and + * will clean up the request if this is the last reference. The caller + * must already have a valid reference to @request, either from + * hdd_request_alloc() or hdd_request_get(). + * + * Returns: Nothing + */ +void hdd_request_put(struct hdd_request *request); + +/** + * hdd_request_wait_for_response() - Wait for a response + * @request: The request struct associated with the request + * + * This function will wait until either a response is received and + * communicated via hdd_request_complete(), or until the request + * timeout period expires. + * + * Returns: 0 if a response was received, -ETIMEDOUT if the response + * timed out. + */ +int hdd_request_wait_for_response(struct hdd_request *request); + +/** + * hdd_request_complete() - Complete a request + * @request: The request struct associated with the request + * + * This function is used to indicate that a response has been received + * and that any information required by the request thread has been + * copied into the private data area of the request struct. This will + * unblock any hdd_request_wait_for_response() that is pending on this + * @request. + * + * Returns: Nothing + */ +void hdd_request_complete(struct hdd_request *request); + +/** + * hdd_request_manager_init() - Initialize the HDD Request Manager + * + * This function must be called during system initialization to + * initialize the HDD Request Manager. + * + * Returns: Nothing + */ +void hdd_request_manager_init(void); + +/** + * hdd_request_manager_deinit() - Deinitialize the HDD Request Manager + * + * This function must be called during system shutdown to deinitialize + * the HDD Request Manager. + * + * Returns: Nothing + */ +void hdd_request_manager_deinit(void); + +#endif /* __WLAN_HDD_REQUEST_MANAGER_H__ */ diff --git a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c index 824c9da2c7d5..121949deb814 100644 --- a/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c +++ b/drivers/staging/qcacld-3.0/core/hdd/src/wlan_hdd_wext.c @@ -94,6 +94,7 @@ #include "wlan_hdd_lro.h" #include "cds_utils.h" #include "wlan_hdd_packet_filter_api.h" +#include "wlan_hdd_request_manager.h" #define HDD_FINISH_ULA_TIME_OUT 800 #define HDD_SET_MCBC_FILTERS_TO_FW 1 @@ -5053,9 +5054,9 @@ static int __iw_get_bitrate(struct net_device *dev, pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); - qdf_status = - qdf_wait_single_event(&pWextState->hdd_qdf_event, - WLAN_WAIT_TIME_STATS); + qdf_status = qdf_wait_for_event_completion( + &pWextState->hdd_qdf_event, + WLAN_WAIT_TIME_STATS); if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("SME timeout while retrieving statistics"); @@ -6051,60 +6052,43 @@ static int iw_get_range(struct net_device *dev, struct iw_request_info *info, return ret; } +struct class_a_stats { + tCsrGlobalClassAStatsInfo class_a_stats; +}; + /** * hdd_get_class_a_statistics_cb() - Get Class A stats callback function - * @pStats: pointer to Class A stats - * @pContext: user context originally registered with SME + * @stats: pointer to Class A stats + * @context: user context originally registered with SME (always the + * cookie from the request context) * * Return: None */ -static void hdd_get_class_a_statistics_cb(void *pStats, void *pContext) +static void hdd_get_class_a_statistics_cb(void *stats, void *context) { - struct statsContext *pStatsContext; - tCsrGlobalClassAStatsInfo *pClassAStats; - hdd_adapter_t *pAdapter; + struct hdd_request *request; + struct class_a_stats *priv; + tCsrGlobalClassAStatsInfo *returned_stats; - if ((NULL == pStats) || (NULL == pContext)) { - hdd_err("Bad param, pStats [%pK] pContext [%pK]", - pStats, pContext); + ENTER(); + if ((NULL == stats) || (NULL == context)) { + hdd_err("Bad param, stats [%p] context [%p]", + stats, context); return; } - pClassAStats = pStats; - pStatsContext = pContext; - pAdapter = pStatsContext->pAdapter; - - /* there is a race condition that exists between this callback - * function and the caller since the caller could time out - * either before or while this code is executing. we use a - * spinlock to serialize these actions - */ - spin_lock(&hdd_context_lock); - - if ((NULL == pAdapter) || - (STATS_CONTEXT_MAGIC != pStatsContext->magic)) { - /* the caller presumably timed out so there is nothing - * we can do - */ - spin_unlock(&hdd_context_lock); - hdd_warn("Invalid context, pAdapter [%pK] magic [%08x]", - pAdapter, pStatsContext->magic); + request = hdd_request_get(context); + if (!request) { + hdd_err("Obsolete request"); return; } - /* context is valid so caller is still waiting */ - - /* paranoia: invalidate the magic */ - pStatsContext->magic = 0; - - /* copy over the stats. do so as a struct copy */ - pAdapter->hdd_stats.ClassA_stat = *pClassAStats; - - /* notify the caller */ - complete(&pStatsContext->completion); - - /* serialization is complete */ - spin_unlock(&hdd_context_lock); + returned_stats = stats; + priv = hdd_request_priv(request); + priv->class_a_stats = *returned_stats; + hdd_request_complete(request); + hdd_request_put(request); + EXIT(); } /** @@ -6117,8 +6101,14 @@ QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter) { hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); QDF_STATUS hstatus; - unsigned long rc; - static struct statsContext context; + int ret; + void *cookie; + struct hdd_request *request; + struct class_a_stats *priv; + static const struct hdd_request_params params = { + .priv_size = sizeof(*priv), + .timeout_ms = WLAN_WAIT_TIME_STATS, + }; if (NULL == pAdapter) { hdd_err("pAdapter is NULL"); @@ -6130,10 +6120,13 @@ QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter) return QDF_STATUS_SUCCESS; } - /* we are connected so prepare our callback context */ - init_completion(&context.completion); - context.pAdapter = pAdapter; - context.magic = STATS_CONTEXT_MAGIC; + request = hdd_request_alloc(¶ms); + if (!request) { + hdd_err("Request allocation failure"); + return QDF_STATUS_E_NOMEM; + } + cookie = hdd_request_cookie(request); + /* query only for Class A statistics (which include link speed) */ hstatus = sme_get_statistics(WLAN_HDD_GET_HAL_CTX(pAdapter), eCSR_HDD, SME_GLOBAL_CLASSA_STATS, @@ -6141,37 +6134,30 @@ QDF_STATUS wlan_hdd_get_class_astats(hdd_adapter_t *pAdapter) 0, /* not periodic */ false, /* non-cached results */ pHddStaCtx->conn_info.staId[0], - &context, pAdapter->sessionId); + cookie, pAdapter->sessionId); if (QDF_STATUS_SUCCESS != hstatus) { hdd_debug("Unable to retrieve Class A statistics"); - /* we'll returned a cached value below */ - } else { - /* request was sent -- wait for the response */ - rc = wait_for_completion_timeout - (&context.completion, - msecs_to_jiffies(WLAN_WAIT_TIME_STATS)); - if (!rc) - hdd_warn("SME timed out while retrieving Class A statistics"); + goto return_cached_results; + } + /* request was sent -- wait for the response */ + ret = hdd_request_wait_for_response(request); + if (ret) { + hdd_warn("SME timed out while retrieving Class A statistics"); + goto return_cached_results; } - /* either we never sent a request, we sent a request and - * received a response or we sent a request and timed out. if - * we never sent a request or if we sent a request and got a - * response, we want to clear the magic out of paranoia. if - * we timed out there is a race condition such that the - * callback function could be executing at the same time we - * are. of primary concern is if the callback function had - * already verified the "magic" but had not yet set the - * completion variable when a timeout occurred. we serialize - * these activities by invalidating the magic while holding a - * shared spinlock which will cause us to block if the - * callback is currently executing + /* update the adapter with the fresh results */ + priv = hdd_request_priv(request); + pAdapter->hdd_stats.ClassA_stat = priv->class_a_stats; + +return_cached_results: + /* + * either we never sent a request, we sent a request and + * received a response or we sent a request and timed out. + * regardless we are done with the request. */ - spin_lock(&hdd_context_lock); - context.magic = 0; - spin_unlock(&hdd_context_lock); + hdd_request_put(request); - /* either callback updated pAdapter stats or it has cached data */ return QDF_STATUS_SUCCESS; } @@ -11858,9 +11844,10 @@ static int __iw_get_statistics(struct net_device *dev, pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); - qdf_status = - qdf_wait_single_event(&pWextState->hdd_qdf_event, - WLAN_WAIT_TIME_STATS); + qdf_status = qdf_wait_for_event_completion( + &pWextState->hdd_qdf_event, + WLAN_WAIT_TIME_STATS); + if (!QDF_IS_STATUS_SUCCESS(qdf_status)) { hdd_err("SME timeout while retrieving statistics"); /* Remove the SME statistics list by diff --git a/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h b/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h index 64c5c9c1e60f..8681739467ff 100644 --- a/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h +++ b/drivers/staging/qcacld-3.0/core/mac/inc/sir_api.h @@ -3566,6 +3566,10 @@ typedef struct sSirRoamOffloadScanReq { #endif struct scoring_param score_params; struct wmi_11k_offload_params offload_11k_params; + uint32_t ho_delay_for_rx; + uint32_t min_delay_btw_roam_scans; + uint32_t roam_trigger_reason_bitmask; + bool roam_force_rssi_trigger; } tSirRoamOffloadScanReq, *tpSirRoamOffloadScanReq; typedef struct sSirRoamOffloadScanRsp { diff --git a/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c b/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c index 56404085797b..1693ecc050a7 100644 --- a/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c +++ b/drivers/staging/qcacld-3.0/core/mac/src/sys/common/src/wlan_qct_sys.c @@ -120,7 +120,8 @@ QDF_STATUS sys_stop(v_CONTEXT_t p_cds_context) if (!QDF_IS_STATUS_SUCCESS(qdf_status)) qdf_status = QDF_STATUS_E_BADMSG; - qdf_status = qdf_wait_single_event(&g_stop_evt, SYS_STOP_TIMEOUT); + qdf_status = qdf_wait_for_event_completion(&g_stop_evt, + SYS_STOP_TIMEOUT); QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); qdf_status = qdf_event_destroy(&g_stop_evt); diff --git a/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c b/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c index b0a8eab4f8a8..2fe092c7b28f 100644 --- a/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c +++ b/drivers/staging/qcacld-3.0/core/sap/src/sap_fsm.c @@ -2558,8 +2558,9 @@ QDF_STATUS sap_open_session(tHalHandle hHal, ptSapContext sapContext, return QDF_STATUS_E_FAILURE; } - status = qdf_wait_single_event(&sapContext->sap_session_opened_evt, - SME_CMD_TIMEOUT_VALUE); + status = qdf_wait_for_event_completion( + &sapContext->sap_session_opened_evt, + SME_CMD_TIMEOUT_VALUE); if (!QDF_IS_STATUS_SUCCESS(status)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h index 1136fd9c655c..b5a4b7c2021d 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_api.h @@ -1303,6 +1303,9 @@ typedef struct tagCsrConfigParam { uint8_t rx_ldpc_support_for_2g; uint8_t max_amsdu_num; uint8_t nSelect5GHzMargin; + uint32_t ho_delay_for_rx; + uint32_t min_delay_btw_roam_scans; + uint32_t roam_trigger_reason_bitmask; uint8_t isCoalesingInIBSSAllowed; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH uint8_t cc_switch_mode; @@ -1392,6 +1395,7 @@ typedef struct tagCsrConfigParam { struct sir_score_config bss_score_params; uint32_t offload_11k_enable_bitmask; struct csr_neighbor_report_offload_params neighbor_report_offload; + bool roam_force_rssi_trigger; } tCsrConfigParam; /* Tush */ diff --git a/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h b/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h index 5090a3191f82..336fe05d4721 100644 --- a/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h +++ b/drivers/staging/qcacld-3.0/core/sme/inc/csr_internal.h @@ -610,6 +610,9 @@ typedef struct tagCsrConfig { bool enableHeartBeatOffload; uint8_t max_amsdu_num; uint8_t nSelect5GHzMargin; + uint32_t ho_delay_for_rx; + uint32_t min_delay_btw_roam_scans; + uint32_t roam_trigger_reason_bitmask; uint8_t isCoalesingInIBSSAllowed; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH uint8_t cc_switch_mode; @@ -676,6 +679,7 @@ typedef struct tagCsrConfig { struct sir_score_config bss_score_params; uint32_t offload_11k_enable_bitmask; struct csr_neighbor_report_offload_params neighbor_report_offload; + bool roam_force_rssi_trigger; } tCsrConfig; typedef struct tagCsrChannelPowerInfo { diff --git a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c index 773420d9d513..e5d0f3f9690e 100644 --- a/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c +++ b/drivers/staging/qcacld-3.0/core/sme/src/csr/csr_api_roam.c @@ -2083,6 +2083,8 @@ csr_fetch_ch_lst_from_received_list(tpAniSirGlobal mac_ctx, } req_buf->ConnectedNetwork.ChannelCount = num_channels; req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; + sme_debug("ChannelCacheType %dChannelCount %d", + req_buf->ChannelCacheType, num_channels); } /** @@ -2693,6 +2695,12 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pParam->max_amsdu_num; pMac->roam.configParam.nSelect5GHzMargin = pParam->nSelect5GHzMargin; + pMac->roam.configParam.ho_delay_for_rx = + pParam->ho_delay_for_rx; + pMac->roam.configParam.min_delay_btw_roam_scans = + pParam->min_delay_btw_roam_scans; + pMac->roam.configParam.roam_trigger_reason_bitmask = + pParam->roam_trigger_reason_bitmask; pMac->roam.configParam.isCoalesingInIBSSAllowed = pParam->isCoalesingInIBSSAllowed; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH @@ -2853,6 +2861,8 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac, pParam->rssi_channel_penalization; pMac->roam.configParam.num_disallowed_aps = pParam->num_disallowed_aps; + pMac->roam.configParam.roam_force_rssi_trigger = + pParam->roam_force_rssi_trigger; qdf_mem_copy(&pMac->roam.configParam.bss_score_params, &pParam->bss_score_params, @@ -3013,6 +3023,10 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) cfg_params->rx_ldpc_support_for_2g; pParam->max_amsdu_num = cfg_params->max_amsdu_num; pParam->nSelect5GHzMargin = cfg_params->nSelect5GHzMargin; + pParam->ho_delay_for_rx = cfg_params->ho_delay_for_rx; + pParam->min_delay_btw_roam_scans = cfg_params->min_delay_btw_roam_scans; + pParam->roam_trigger_reason_bitmask = + cfg_params->roam_trigger_reason_bitmask; pParam->isCoalesingInIBSSAllowed = cfg_params->isCoalesingInIBSSAllowed; pParam->allowDFSChannelRoam = cfg_params->allowDFSChannelRoam; pParam->nInitialDwellTime = cfg_params->nInitialDwellTime; @@ -3155,6 +3169,7 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pMac->roam.configParam.rssi_channel_penalization; pParam->num_disallowed_aps = pMac->roam.configParam.num_disallowed_aps; + pParam->roam_force_rssi_trigger = cfg_params->roam_force_rssi_trigger; qdf_mem_copy(&pParam->bss_score_params, &pMac->roam.configParam.bss_score_params, @@ -18025,6 +18040,14 @@ csr_update_roam_scan_offload_request(tpAniSirGlobal mac_ctx, req_buf->Prefer5GHz = mac_ctx->roam.configParam.nRoamPrefer5GHz; req_buf->RoamRssiCatGap = mac_ctx->roam.configParam.bCatRssiOffset; req_buf->Select5GHzMargin = mac_ctx->roam.configParam.nSelect5GHzMargin; + req_buf->ho_delay_for_rx = mac_ctx->roam.configParam.ho_delay_for_rx; + req_buf->min_delay_btw_roam_scans = + mac_ctx->roam.configParam.min_delay_btw_roam_scans; + req_buf->roam_trigger_reason_bitmask = + mac_ctx->roam.configParam.roam_trigger_reason_bitmask; + req_buf->roam_force_rssi_trigger = + mac_ctx->roam.configParam.roam_force_rssi_trigger; + if (wlan_cfg_get_int(mac_ctx, WNI_CFG_REASSOCIATION_FAILURE_TIMEOUT, (uint32_t *) &req_buf->ReassocFailureTimeout) != eSIR_SUCCESS) { @@ -18158,6 +18181,8 @@ csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx, } req_buf->ConnectedNetwork.ChannelCount = num_channels; req_buf->ChannelCacheType = CHANNEL_LIST_STATIC; + sme_debug("ChannelCacheType %dChannelCount %d", + req_buf->ChannelCacheType, num_channels); return QDF_STATUS_SUCCESS; } @@ -18258,6 +18283,8 @@ csr_fetch_ch_lst_from_occupied_lst(tpAniSirGlobal mac_ctx, else req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; } + sme_debug("ChannelCacheType %dChannelCount %d", + req_buf->ChannelCacheType, num_channels); } /** @@ -18359,11 +18386,10 @@ csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx, } req_buf->ValidChannelCount = num_channels; - if (CSR_IS_ROAM_INTRA_BAND_ENABLED(mac_ctx)) { - req_buf->ChannelCacheType = CHANNEL_LIST_STATIC; - req_buf->ConnectedNetwork.ChannelCount = num_channels; - } - + req_buf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE; + req_buf->ConnectedNetwork.ChannelCount = num_channels; + sme_debug("ChannelCacheType %dChannelCount %d", + req_buf->ChannelCacheType, num_channels); return status; } diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c index bc7ec1179478..698af36e2fea 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_data.c @@ -3030,7 +3030,7 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, * @ Discrete : Target Download Complete */ qdf_status = - qdf_wait_single_event(&wma_handle-> + qdf_wait_for_event_completion(&wma_handle-> tx_frm_download_comp_event, WMA_TX_FRAME_COMPLETE_TIMEOUT); diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c index f8cdc6524479..707c0b97cec1 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_dev_if.c @@ -5069,7 +5069,7 @@ static void wma_wait_tx_complete(tp_wma_handle wma, while (ol_txrx_get_tx_pending(pdev) && max_wait_iterations) { WMA_LOGW(FL("Waiting for outstanding packet to drain.")); - qdf_wait_single_event(&wma->tx_queue_empty_event, + qdf_wait_for_event_completion(&wma->tx_queue_empty_event, WMA_TX_Q_RECHECK_TIMER_WAIT); max_wait_iterations--; } diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c index 65315642688a..b74f516c456f 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_features.c @@ -5350,7 +5350,7 @@ QDF_STATUS wma_enable_d0wow_in_fw(WMA_HANDLE handle) return status; } - status = qdf_wait_single_event(&wma->target_suspend, + status = qdf_wait_for_event_completion(&wma->target_suspend, WMA_TGT_SUSPEND_COMPLETE_TIMEOUT); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("Failed to receive D0-WoW enable HTC ACK from FW! " @@ -5450,7 +5450,7 @@ QDF_STATUS wma_enable_wow_in_fw(WMA_HANDLE handle, uint32_t wow_flags) wmi_set_target_suspend(wma->wmi_handle, true); - if (qdf_wait_single_event(&wma->target_suspend, + if (qdf_wait_for_event_completion(&wma->target_suspend, WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to receive WoW Enable Ack from FW"); @@ -6215,7 +6215,7 @@ static QDF_STATUS wma_send_host_wakeup_ind_to_fw(tp_wma_handle wma) WMA_LOGD("Host wakeup indication sent to fw"); - qdf_status = qdf_wait_single_event(&(wma->wma_resume_event), + qdf_status = qdf_wait_for_event_completion(&(wma->wma_resume_event), WMA_RESUME_TIMEOUT); if (QDF_STATUS_SUCCESS != qdf_status) { WMA_LOGP("%s: Timeout waiting for resume event from FW", @@ -6271,7 +6271,7 @@ QDF_STATUS wma_disable_d0wow_in_fw(WMA_HANDLE handle) return status; } - status = qdf_wait_single_event(&(wma->wma_resume_event), + status = qdf_wait_for_event_completion(&(wma->wma_resume_event), WMA_RESUME_TIMEOUT); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGP("%s: Timeout waiting for resume event from FW!", @@ -8173,7 +8173,7 @@ static QDF_STATUS wma_post_runtime_suspend_msg(WMA_HANDLE handle) if (qdf_status != QDF_STATUS_SUCCESS) goto failure; - if (qdf_wait_single_event(&wma->runtime_suspend, + if (qdf_wait_for_event_completion(&wma->runtime_suspend, WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to get runtime suspend event"); @@ -8446,7 +8446,7 @@ QDF_STATUS wma_suspend_target(WMA_HANDLE handle, int disable_target_intr) wmi_set_target_suspend(wma_handle->wmi_handle, true); - if (qdf_wait_single_event(&wma_handle->target_suspend, + if (qdf_wait_for_event_completion(&wma_handle->target_suspend, WMA_TGT_SUSPEND_COMPLETE_TIMEOUT) != QDF_STATUS_SUCCESS) { WMA_LOGE("Failed to get ACK from firmware for pdev suspend"); @@ -8570,7 +8570,7 @@ QDF_STATUS wma_resume_target(WMA_HANDLE handle) if (QDF_IS_STATUS_ERROR(qdf_status)) WMA_LOGE("Failed to send WMI_PDEV_RESUME_CMDID command"); - qdf_status = qdf_wait_single_event(&(wma->wma_resume_event), + qdf_status = qdf_wait_for_event_completion(&(wma->wma_resume_event), WMA_RESUME_TIMEOUT); if (QDF_STATUS_SUCCESS != qdf_status) { WMA_LOGP("%s: Timeout waiting for resume event from FW", diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c index 22f862b64c0a..d219c1a17f15 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_main.c @@ -6118,8 +6118,9 @@ QDF_STATUS wma_wait_for_ready_event(WMA_HANDLE handle) QDF_STATUS qdf_status; /* wait until WMI_READY_EVENTID received from FW */ - qdf_status = qdf_wait_single_event(&(wma_handle->wma_ready_event), - WMA_READY_EVENTID_TIMEOUT); + qdf_status = qdf_wait_for_event_completion( + &wma_handle->wma_ready_event, + WMA_READY_EVENTID_TIMEOUT); if (QDF_STATUS_SUCCESS != qdf_status) { WMA_LOGE("%s: Timeout waiting for ready event from FW", diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c index da3df9629c14..9300ce61b7a5 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_scan_roam.c @@ -875,6 +875,8 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, params->is_roam_req_valid = 1; #ifdef WLAN_FEATURE_ROAM_OFFLOAD params->roam_offload_enabled = roam_req->RoamOffloadEnabled; + params->roam_offload_params.ho_delay_for_rx = + roam_req->ho_delay_for_rx; params->prefer_5ghz = roam_req->Prefer5GHz; params->roam_rssi_cat_gap = roam_req->RoamRssiCatGap; params->select_5ghz_margin = roam_req->Select5GHzMargin; @@ -895,6 +897,10 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, params->fw_okc = roam_req->pmkid_modes.fw_okc; params->fw_pmksa_cache = roam_req->pmkid_modes.fw_pmksa_cache; #endif + params->min_delay_btw_roam_scans = + roam_req->min_delay_btw_roam_scans; + params->roam_trigger_reason_bitmask = + roam_req->roam_trigger_reason_bitmask; params->is_ese_assoc = roam_req->IsESEAssoc; params->mdid.mdie_present = roam_req->MDID.mdiePresent; params->mdid.mobility_domain = roam_req->MDID.mobilityDomain; @@ -905,10 +911,14 @@ QDF_STATUS wma_roam_scan_offload_mode(tp_wma_handle wma_handle, wma_roam_scan_fill_fils_params(wma_handle, params, roam_req); } - WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, roam_scan_mode: %d"), + WMA_LOGD(FL("qos_caps: %d, qos_enabled: %d, ho_delay_for_rx: %d, roam_scan_mode: %d"), params->roam_offload_params.qos_caps, params->roam_offload_params.qos_enabled, - params->mode); + params->roam_offload_params.ho_delay_for_rx, params->mode); + + WMA_LOGD(FL("min_delay_btw_roam_scans: %d, roam_trigger_reason_bitmask: %d"), + params->min_delay_btw_roam_scans, + params->roam_trigger_reason_bitmask); status = wmi_unified_roam_scan_offload_mode_cmd(wma_handle->wmi_handle, scan_cmd_fp, params); @@ -1972,7 +1982,8 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, /* Don't use rssi triggered roam scans if external app * is in control of channel list. */ - if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) + if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC || + roam_req->roam_force_rssi_trigger) mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; } else { @@ -2239,7 +2250,8 @@ QDF_STATUS wma_process_roaming_config(tp_wma_handle wma_handle, /* Don't use rssi triggered roam scans if external app * is in control of channel list. */ - if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC) + if (roam_req->ChannelCacheType != CHANNEL_LIST_STATIC || + roam_req->roam_force_rssi_trigger) mode |= WMI_ROAM_SCAN_MODE_RSSI_CHANGE; } else { diff --git a/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c b/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c index 001849e9b1c8..f314c7eba420 100644 --- a/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c +++ b/drivers/staging/qcacld-3.0/core/wma/src/wma_utils.c @@ -1526,8 +1526,8 @@ static int wma_unified_radio_tx_power_level_stats_event_handler(void *handle, return -EINVAL; } - if (fixed_param->radio_id > link_stats_results->num_radio) { - WMA_LOGD("%s: Invalid radio_id %d num_radio %d", + if (fixed_param->radio_id >= link_stats_results->num_radio) { + WMA_LOGE("%s: Invalid radio_id %d num_radio %d", __func__, fixed_param->radio_id, link_stats_results->num_radio); return -EINVAL; @@ -1692,6 +1692,13 @@ static int wma_unified_link_radio_stats_event_handler(void *handle, link_stats_results_size = sizeof(*link_stats_results) + fixed_param->num_radio * radio_stats_size; + if (radio_stats->radio_id >= fixed_param->num_radio) { + WMA_LOGE("%s: Invalid radio_id %d num_radio %d", + __func__, radio_stats->radio_id, + fixed_param->num_radio); + return -EINVAL; + } + if (!wma_handle->link_stats_results) { wma_handle->link_stats_results = qdf_mem_malloc( link_stats_results_size);