From 6982d47826c88542176ef3fcd5ce483e50173ccc Mon Sep 17 00:00:00 2001 From: gaurank kathpalia Date: Wed, 31 Oct 2018 21:54:15 +0530 Subject: [PATCH] qcacld-3.0: Accept the dynamic command only in started state Accept the command to change the dynamic params like nss and chains only when the vdev is in connected state for STA/P2P-CLI, and in start state in case of SAP/P2P-GO. Change-Id: Id4d2e3c4ac6745e25c7005af0b3c95e3e1db4533 CRs-Fixed: 2347488 --- core/hdd/inc/wlan_hdd_main.h | 12 ++++++++++++ core/hdd/src/wlan_hdd_cfg.c | 6 ++++++ core/hdd/src/wlan_hdd_ioctl.c | 12 ++++++------ core/hdd/src/wlan_hdd_main.c | 21 +++++++++++++++++++++ core/wma/src/wma_utils.c | 16 +++++++++++++--- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index 9e77c15c7028..25050b6b1d84 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2199,6 +2199,18 @@ struct hdd_adapter * hdd_get_adapter_by_rand_macaddr(struct hdd_context *hdd_ctx, tSirMacAddr mac_addr); +/** + * hdd_is_vdev_in_conn_state() - Check whether the vdev is in + * connected/started state. + * @adapter: hdd adapter of the vdev + * + * This function will give whether the vdev in the adapter is in + * connected/started state. + * + * Return: True/false + */ +bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter); + int hdd_vdev_create(struct hdd_adapter *adapter, csr_roam_complete_cb callback, void *ctx); int hdd_vdev_destroy(struct hdd_adapter *adapter); diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c index 3bf0aef7271c..15a0b95d08e5 100644 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -4370,6 +4370,12 @@ hdd_set_nss_params(struct hdd_adapter *adapter, return QDF_STATUS_E_INVAL; } + if (!hdd_is_vdev_in_conn_state(adapter)) { + hdd_debug("Vdev (id %d) not in connected/started state, cannot accept command", + adapter->session_id); + return QDF_STATUS_E_FAILURE; + } + for (band = BAND_2GHZ; band < NUM_OF_BANDS; band++) hdd_populate_vdev_nss(&user_cfg, tx_nss, rx_nss, band); diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index 97abc5a1651c..bbe93f121276 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/core/hdd/src/wlan_hdd_ioctl.c @@ -6701,6 +6701,12 @@ hdd_set_dynamic_antenna_mode(struct hdd_adapter *adapter, return -EINVAL; } + if (!hdd_is_vdev_in_conn_state(adapter)) { + hdd_debug("Vdev (id %d) not in connected/started state, cannot accept command", + adapter->session_id); + return -EINVAL; + } + qdf_mem_zero(&user_cfg, sizeof(user_cfg)); for (band = BAND_2GHZ; band < BAND_MAX; band++) { status = hdd_populate_vdev_chains(&user_cfg, @@ -6750,11 +6756,6 @@ int hdd_set_antenna_mode(struct hdd_adapter *adapter, params.num_rx_chains, params.num_tx_chains); - if (hdd_ctx->current_antenna_mode == mode) { - hdd_err("System already in the requested mode"); - goto exit; - } - if ((HDD_ANTENNA_MODE_2X2 == mode) && (!hdd_is_supported_chain_mask_2x2(hdd_ctx))) { hdd_err("System does not support 2x2 mode"); @@ -6768,7 +6769,6 @@ int hdd_set_antenna_mode(struct hdd_adapter *adapter, goto exit; } - /* Check TDLS status and update antenna mode */ if ((QDF_STA_MODE == adapter->device_mode) && policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc)) { diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 1431964288d5..1bca38f4a239 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -4058,6 +4058,27 @@ hdd_store_nss_chains_cfg_in_vdev(struct hdd_adapter *adapter) qdf_mem_copy(mlme_get_ini_vdev_config(adapter->vdev), &vdev_ini_cfg, sizeof(struct wlan_mlme_nss_chains)); } + +bool hdd_is_vdev_in_conn_state(struct hdd_adapter *adapter) +{ + switch (adapter->device_mode) { + case QDF_STA_MODE: + case QDF_P2P_CLIENT_MODE: + case QDF_P2P_DEVICE_MODE: + return hdd_conn_is_connected( + WLAN_HDD_GET_STATION_CTX_PTR(adapter)); + case QDF_SAP_MODE: + case QDF_P2P_GO_MODE: + return (test_bit(SOFTAP_BSS_STARTED, + &adapter->event_flags)); + default: + hdd_err("Device mode %d invalid", adapter->device_mode); + return 0; + } + + return 0; +} + int hdd_vdev_create(struct hdd_adapter *adapter, csr_roam_complete_cb callback, void *ctx) { diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 4c0c64a17fa2..93f1bffb341f 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -4403,18 +4403,28 @@ wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params) QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) { QDF_STATUS status; - struct wma_txrx_node *vdev = &wma->interfaces[vdev_id]; + struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; if (!wma_is_vdev_valid(vdev_id)) { WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id); status = QDF_STATUS_E_FAILURE; return status; } - wma_acquire_wakelock(&vdev->vdev_stop_wakelock, + + /** + * Reset the dynamic nss chains config to the ini values, as when the + * vdev gets its started again, this would be a fresh connection, + * and we dont want the config of previous connection to affect the + * current connection. + */ + qdf_mem_copy(mlme_get_dynamic_vdev_config(iface->vdev), + mlme_get_ini_vdev_config(iface->vdev), + sizeof(struct wlan_mlme_nss_chains)); + wma_acquire_wakelock(&iface->vdev_stop_wakelock, WMA_VDEV_STOP_REQUEST_TIMEOUT); status = wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id); if (QDF_IS_STATUS_ERROR(status)) - wma_release_wakelock(&vdev->vdev_stop_wakelock); + wma_release_wakelock(&iface->vdev_stop_wakelock); return status; }