summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cds/inc/cds_api.h2
-rw-r--r--core/cds/inc/cds_sched.h2
-rw-r--r--core/cds/src/cds_api.c95
-rw-r--r--core/cds/src/cds_concurrency.c404
-rw-r--r--core/hdd/src/wlan_hdd_cfg80211.c2
-rw-r--r--core/hdd/src/wlan_hdd_ext_scan.c7
-rw-r--r--core/hdd/src/wlan_hdd_ioctl.c4
-rw-r--r--core/hdd/src/wlan_hdd_ipa.c125
-rw-r--r--core/hdd/src/wlan_hdd_main.c8
-rw-r--r--core/hdd/src/wlan_hdd_memdump.c2
-rw-r--r--core/hdd/src/wlan_hdd_power.c2
-rw-r--r--core/hdd/src/wlan_hdd_wext.c10
-rw-r--r--core/mac/inc/qwlan_version.h4
-rw-r--r--core/mac/inc/sir_mac_prot_def.h4
-rw-r--r--core/mac/src/pe/lim/lim_process_action_frame.c24
-rw-r--r--core/mac/src/pe/lim/lim_process_sme_req_messages.c32
-rw-r--r--core/mac/src/pe/lim/lim_utils.c73
-rw-r--r--core/mac/src/pe/lim/lim_utils.h9
-rw-r--r--core/sme/src/common/sme_api.c134
-rw-r--r--core/sme/src/csr/csr_api_roam.c2
-rw-r--r--core/wma/src/wma_data.c34
-rw-r--r--core/wma/src/wma_dev_if.c39
-rw-r--r--core/wma/src/wma_main.c13
-rw-r--r--core/wma/src/wma_utils.c4
24 files changed, 804 insertions, 231 deletions
diff --git a/core/cds/inc/cds_api.h b/core/cds/inc/cds_api.h
index 807e4aa64779..1ecabb01b6c8 100644
--- a/core/cds/inc/cds_api.h
+++ b/core/cds/inc/cds_api.h
@@ -213,6 +213,8 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context);
*/
void cds_flush_cache_rx_queue(void);
+QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context);
+
QDF_STATUS cds_close(v_CONTEXT_t cds_context);
void cds_core_return_msg(void *pVContext, p_cds_msg_wrapper pMsgWrapper);
diff --git a/core/cds/inc/cds_sched.h b/core/cds/inc/cds_sched.h
index 9739ec4126ca..0fcb95f2db23 100644
--- a/core/cds/inc/cds_sched.h
+++ b/core/cds/inc/cds_sched.h
@@ -321,8 +321,6 @@ typedef struct _cds_context_type {
bool do_hw_mode_change;
bool enable_fatal_event;
struct cds_config_info *cds_cfg;
- /* WAR: Is cds disabled */
- bool is_cds_disabled;
} cds_context_type, *p_cds_contextType;
/*---------------------------------------------------------------------------
diff --git a/core/cds/src/cds_api.c b/core/cds/src/cds_api.c
index 26c01c1a412f..ff84def298ec 100644
--- a/core/cds/src/cds_api.c
+++ b/core/cds/src/cds_api.c
@@ -245,6 +245,14 @@ QDF_STATUS cds_open(void)
QDF_ASSERT(0);
goto err_msg_queue;
}
+
+ if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
+ &cds_ctx->qdf_conc_list_lock))) {
+ cds_err("Failed to init qdf_conc_list_lock");
+ QDF_ASSERT(0);
+ goto err_msg_queue;
+ }
+
/* Now Open the CDS Scheduler */
if (pHddCtx->driver_status == DRIVER_MODULES_UNINITIALIZED ||
@@ -258,7 +266,7 @@ QDF_STATUS cds_open(void)
QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL,
"%s: Failed to open CDS Scheduler", __func__);
QDF_ASSERT(0);
- goto err_msg_queue;
+ goto err_concurrency_lock;
}
}
@@ -415,6 +423,9 @@ err_bmi_close:
err_sched_close:
cds_sched_close(gp_cds_context);
+err_concurrency_lock:
+ qdf_mutex_destroy(&cds_ctx->qdf_conc_list_lock);
+
err_msg_queue:
cds_mq_deinit(&gp_cds_context->freeVosMq);
@@ -688,9 +699,6 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
wma_setneedshutdown(cds_context);
}
- hif_disable_isr(((cds_context_type *) cds_context)->pHIFContext);
- hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
-
handle = cds_get_context(QDF_MODULE_ID_PE);
if (!handle) {
cds_err("Invalid PE context return!");
@@ -708,27 +716,51 @@ QDF_STATUS cds_disable(v_CONTEXT_t cds_context)
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
- gp_cds_context->is_cds_disabled = 1;
return qdf_status;
}
+#ifdef HIF_USB
+static inline void cds_suspend_target(tp_wma_handle wma_handle)
+{
+ QDF_STATUS status;
+ /* Suspend the target and disable interrupt */
+ status = wma_suspend_target(wma_handle, 0);
+ if (status)
+ cds_err("Failed to suspend target, status = %d", status);
+}
+#else
+static inline void cds_suspend_target(tp_wma_handle wma_handle)
+{
+ QDF_STATUS status;
+ /* Suspend the target and disable interrupt */
+ status = wma_suspend_target(wma_handle, 1);
+ if (status)
+ cds_err("Failed to suspend target, status = %d", status);
+}
+#endif /* HIF_USB */
+
/**
- * cds_close() - close cds module
+ * cds_post_disable() - post disable cds module
* @cds_context: CDS context
*
* Return: QDF status
*/
-QDF_STATUS cds_close(v_CONTEXT_t cds_context)
+QDF_STATUS cds_post_disable(v_CONTEXT_t cds_context)
{
- QDF_STATUS qdf_status;
tp_wma_handle wma_handle;
-
+ struct hif_opaque_softc *hif_ctx;
wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
if (!wma_handle) {
cds_err("Failed to get wma_handle!");
return QDF_STATUS_E_INVAL;
}
+ hif_ctx = cds_get_context(QDF_MODULE_ID_HIF);
+ if (!hif_ctx) {
+ cds_err("Failed to get hif_handle!");
+ return QDF_STATUS_E_INVAL;
+ }
+
/*
* With new state machine changes cds_close can be invoked without
* cds_disable. So, send the following clean up prerequisites to fw,
@@ -738,23 +770,27 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
* - Clean up CE tasklets.
*/
- if (!gp_cds_context->is_cds_disabled) {
- cds_info("send denint sequence to firmware");
- if (!cds_is_driver_recovering()) {
-#ifdef HIF_USB
- /* Suspend the target and enable interrupt */
- if (wma_suspend_target(wma_handle, 0))
- cds_err("Failed to suspend target");
-#else
- /* Suspend the target and disable interrupt */
- if (wma_suspend_target(wma_handle, 1))
- cds_err("Failed to suspend target");
-#endif /* HIF_USB */
- }
- hif_disable_isr(
- ((cds_context_type *) cds_context)->pHIFContext);
- hif_reset_soc(((cds_context_type *) cds_context)->pHIFContext);
- }
+ cds_info("send denint sequence to firmware");
+ if (!cds_is_driver_recovering())
+ cds_suspend_target(wma_handle);
+ hif_disable_isr(hif_ctx);
+ hif_reset_soc(hif_ctx);
+
+ return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cds_close() - close cds module
+ * @cds_context: CDS context
+ *
+ * This API allows user to close modules registered
+ * with connectivity device services.
+ *
+ * Return: QDF status
+ */
+QDF_STATUS cds_close(v_CONTEXT_t cds_context)
+{
+ QDF_STATUS qdf_status;
qdf_status = wma_wmi_work_close(cds_context);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
@@ -824,13 +860,18 @@ QDF_STATUS cds_close(v_CONTEXT_t cds_context)
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
}
+ if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(
+ &gp_cds_context->qdf_conc_list_lock))) {
+ cds_err("Failed to destroy qdf_conc_list_lock");
+ QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
+ }
+
cds_shutdown_notifier_purge();
cds_deinit_log_completion();
cds_deinit_ini_config();
qdf_timer_module_deinit();
- gp_cds_context->is_cds_disabled = 0;
return QDF_STATUS_SUCCESS;
}
diff --git a/core/cds/src/cds_concurrency.c b/core/cds/src/cds_concurrency.c
index 254d782ccfa4..0940968ed4cb 100644
--- a/core/cds/src/cds_concurrency.c
+++ b/core/cds/src/cds_concurrency.c
@@ -1962,12 +1962,21 @@ next_action_three_connection_table[CDS_MAX_TWO_CONNECTION_MODE]
uint32_t cds_get_connection_count(void)
{
uint32_t conn_index, count = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return count;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if (conc_connection_list[conn_index].in_use)
count++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return count;
}
@@ -2173,6 +2182,14 @@ uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode,
uint32_t *list)
{
uint32_t conn_index = 0, count = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return count;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].mode == mode) &&
@@ -2182,6 +2199,7 @@ uint32_t cds_mode_specific_connection_count(enum cds_con_mode mode,
count++;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return count;
}
@@ -2201,7 +2219,15 @@ static void cds_store_and_del_conn_info(enum cds_con_mode mode,
{
uint32_t conn_index = 0;
bool found = false;
+ cds_context_type *cds_ctx;
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (mode == conc_connection_list[conn_index].mode) {
found = true;
@@ -2211,12 +2237,14 @@ static void cds_store_and_del_conn_info(enum cds_con_mode mode,
}
if (!found) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("Mode:%d not available in the conn info", mode);
return;
}
/* Storing the STA entry which will be temporarily deleted */
*info = conc_connection_list[conn_index];
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
/* Deleting the STA entry */
cds_decr_connection_count(info->vdev_id);
@@ -2240,6 +2268,13 @@ static void cds_restore_deleted_conn_info(
struct cds_conc_connection_info *info)
{
uint32_t conn_index;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
conn_index = cds_get_connection_count();
if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
@@ -2248,7 +2283,9 @@ static void cds_restore_deleted_conn_info(
return;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
conc_connection_list[conn_index] = *info;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_info("Restored the deleleted conn info, vdev:%d, index:%d",
info->vdev_id, conn_index);
@@ -2297,8 +2334,8 @@ static void cds_update_hw_mode_conn_info(uint32_t num_vdev_mac_entries,
conc_connection_list[conn_index].mac);
}
}
- cds_dump_connection_status_info();
qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ cds_dump_connection_status_info();
}
/**
@@ -2763,8 +2800,18 @@ static uint32_t cds_dump_current_concurrency_one_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
+ enum cds_con_mode mode;
+ cds_context_type *cds_ctx;
- switch (conc_connection_list[0].mode) {
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return count;
+ }
+
+ mode = conc_connection_list[0].mode;
+
+ switch (mode) {
case CDS_STA_MODE:
count = strlcat(cc_mode, "STA",
length);
@@ -2786,7 +2833,7 @@ static uint32_t cds_dump_current_concurrency_one_connection(char *cc_mode,
length);
break;
default:
- cds_err("unexpected mode %d", conc_connection_list[0].mode);
+ cds_err("unexpected mode %d", mode);
break;
}
return count;
@@ -2806,8 +2853,18 @@ static uint32_t cds_dump_current_concurrency_two_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
+ enum cds_con_mode mode;
+ cds_context_type *cds_ctx;
- switch (conc_connection_list[1].mode) {
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return count;
+ }
+
+ mode = conc_connection_list[1].mode;
+
+ switch (mode) {
case CDS_STA_MODE:
count = cds_dump_current_concurrency_one_connection(
cc_mode, length);
@@ -2839,7 +2896,7 @@ static uint32_t cds_dump_current_concurrency_two_connection(char *cc_mode,
length);
break;
default:
- cds_err("unexpected mode %d", conc_connection_list[1].mode);
+ cds_err("unexpected mode %d", mode);
break;
}
return count;
@@ -2859,8 +2916,18 @@ static uint32_t cds_dump_current_concurrency_three_connection(char *cc_mode,
uint32_t length)
{
uint32_t count = 0;
+ enum cds_con_mode mode;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return count;
+ }
+
+ mode = conc_connection_list[2].mode;
- switch (conc_connection_list[2].mode) {
+ switch (mode) {
case CDS_STA_MODE:
count = cds_dump_current_concurrency_two_connection(
cc_mode, length);
@@ -2892,7 +2959,7 @@ static uint32_t cds_dump_current_concurrency_three_connection(char *cc_mode,
length);
break;
default:
- cds_err("unexpected mode %d", conc_connection_list[2].mode);
+ cds_err("unexpected mode %d", mode);
break;
}
return count;
@@ -2911,8 +2978,16 @@ static void cds_dump_dbs_concurrency(char *cc_mode, uint32_t length)
{
char buf[4] = {0};
uint8_t mac = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
strlcat(cc_mode, " DBS", length);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (conc_connection_list[0].mac ==
conc_connection_list[1].mac) {
if (conc_connection_list[0].chan ==
@@ -2950,6 +3025,7 @@ static void cds_dump_dbs_concurrency(char *cc_mode, uint32_t length)
length);
mac = conc_connection_list[1].mac;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
snprintf(buf, sizeof(buf), "%d ", mac);
strlcat(cc_mode, buf, length);
}
@@ -2967,6 +3043,13 @@ static void cds_dump_current_concurrency(void)
uint32_t num_connections = 0;
char cc_mode[CDS_MAX_CON_STRING_LEN] = {0};
uint32_t count = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
num_connections = cds_get_connection_count();
@@ -2979,6 +3062,7 @@ static void cds_dump_current_concurrency(void)
case 2:
count = cds_dump_current_concurrency_two_connection(
cc_mode, sizeof(cc_mode));
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (conc_connection_list[0].chan ==
conc_connection_list[1].chan) {
strlcat(cc_mode, " SCC", sizeof(cc_mode));
@@ -2987,24 +3071,29 @@ static void cds_dump_current_concurrency(void)
strlcat(cc_mode, " MCC", sizeof(cc_mode));
} else
strlcat(cc_mode, " DBS", sizeof(cc_mode));
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("%s", cc_mode);
break;
case 3:
count = cds_dump_current_concurrency_three_connection(
cc_mode, sizeof(cc_mode));
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if ((conc_connection_list[0].chan ==
conc_connection_list[1].chan) &&
(conc_connection_list[0].chan ==
conc_connection_list[2].chan)){
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
strlcat(cc_mode, " SCC",
sizeof(cc_mode));
} else if ((conc_connection_list[0].mac ==
conc_connection_list[1].mac)
&& (conc_connection_list[0].mac ==
conc_connection_list[2].mac)) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
strlcat(cc_mode, " MCC on single MAC",
sizeof(cc_mode));
} else {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_dump_dbs_concurrency(cc_mode, sizeof(cc_mode));
}
cds_err("%s", cc_mode);
@@ -3084,6 +3173,7 @@ void cds_dump_concurrency_info(void)
uint8_t staChannel = 0, p2pChannel = 0, apChannel = 0;
const char *p2pMode = "DEV";
hdd_context_t *hdd_ctx;
+ cds_context_type *cds_ctx;
#ifdef QCA_LL_LEGACY_TX_FLOW_CONTROL
uint8_t targetChannel = 0;
uint8_t preAdapterChannel = 0;
@@ -3100,6 +3190,12 @@ void cds_dump_concurrency_info(void)
return;
}
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return;
+ }
+
status = hdd_get_front_adapter(hdd_ctx, &adapterNode);
while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
adapter = adapterNode->pAdapter;
@@ -3345,7 +3441,9 @@ void cds_dump_concurrency_info(void)
status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
adapterNode = pNext;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
hdd_ctx->mcc_mode = cds_current_concurrency_is_mcc();
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
#ifdef FEATURE_WLAN_TDLS
@@ -3671,21 +3769,24 @@ void cds_incr_active_session(enum tQDF_ADAPTER_MODE mode,
cds_info("No.# of active sessions for mode %d = %d",
mode, hdd_ctx->no_of_active_sessions[mode]);
-
/*
* Get PCL logic makes use of the connection info structure.
* Let us set the PCL to the FW before updating the connection
* info structure about the new connection.
*/
if (mode == QDF_STA_MODE) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
/* Set PCL of STA to the FW */
cds_pdev_set_pcl(mode);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
cds_info("Set PCL of STA to FW");
}
cds_incr_connection_count(session_id);
if ((cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0) &&
(mode != QDF_STA_MODE)) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_set_pcl_for_existing_combo(CDS_STA_MODE);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
}
/* set tdls connection tracker state */
@@ -3711,6 +3812,13 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
uint8_t mac = 0;
struct sir_hw_mode_params hw_mode;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ goto done;
+ }
if (wma_is_hw_dbs_capable() == false) {
cds_err("driver isn't dbs capable, no further action needed");
@@ -3727,6 +3835,7 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
goto done;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
/* Are both mac's still in use */
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
@@ -3739,13 +3848,17 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
if ((conc_connection_list[conn_index].mac == 0) &&
conc_connection_list[conn_index].in_use) {
mac |= CDS_MAC0;
- if (CDS_MAC0_AND_MAC1 == mac)
+ if (CDS_MAC0_AND_MAC1 == mac) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
+ }
} else if ((conc_connection_list[conn_index].mac == 1) &&
conc_connection_list[conn_index].in_use) {
mac |= CDS_MAC1;
- if (CDS_MAC0_AND_MAC1 == mac)
+ if (CDS_MAC0_AND_MAC1 == mac) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
+ }
}
}
/* Let's request for single MAC mode */
@@ -3756,9 +3869,11 @@ enum cds_conc_next_action cds_need_opportunistic_upgrade(void)
if ((conc_connection_list[conn_index].original_nss == 2) &&
conc_connection_list[conn_index].in_use) {
upgrade = CDS_SINGLE_MAC_UPGRADE;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
done:
return upgrade;
@@ -3792,7 +3907,6 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
cds_info("get pcl for existing conn:%d", mode);
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (cds_mode_specific_connection_count(mode, NULL) > 0) {
/* Check, store and temp delete the mode's parameter */
cds_store_and_del_conn_info(mode, &info);
@@ -3802,7 +3916,6 @@ QDF_STATUS cds_get_pcl_for_existing_conn(enum cds_con_mode mode,
/* Restore the connection info */
cds_restore_deleted_conn_info(&info);
}
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -3843,7 +3956,6 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode,
* given to the FW. After setting the PCL, we need to restore
* the entry that we have saved before.
*/
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
cds_set_pcl_for_existing_combo(CDS_STA_MODE);
/* do we need to change the HW mode */
if (cds_need_opportunistic_upgrade()) {
@@ -3856,7 +3968,6 @@ void cds_decr_session_set_pcl(enum tQDF_ADAPTER_MODE mode,
if (!QDF_IS_STATUS_SUCCESS(qdf_status))
cds_err("Failed to start dbs opportunistic timer");
}
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return;
}
@@ -3877,7 +3988,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
uint8_t session_id)
{
hdd_context_t *hdd_ctx;
- cds_context_type *cds_ctx;
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -3885,17 +3995,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
return;
}
- cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
- if (!cds_ctx) {
- cds_err("Invalid CDS Context");
- return;
- }
-
- /*
- * Need to aquire mutex as entire functionality in this function
- * is in critical section
- */
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
switch (mode) {
case QDF_STA_MODE:
case QDF_P2P_CLIENT_MODE:
@@ -3919,7 +4018,6 @@ void cds_decr_active_session(enum tQDF_ADAPTER_MODE mode,
cds_dump_current_concurrency();
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
/**
@@ -3941,7 +4039,6 @@ static void cds_dbs_opportunistic_timer_handler(void *data)
return;
}
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
/* if we still need it */
action = cds_need_opportunistic_upgrade();
cds_info("action:%d", action);
@@ -3954,7 +4051,6 @@ static void cds_dbs_opportunistic_timer_handler(void *data)
cds_next_actions(0, action,
SIR_UPDATE_REASON_OPPORTUNISTIC);
}
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
@@ -3984,13 +4080,6 @@ QDF_STATUS cds_deinit_policy_mgr(void)
QDF_ASSERT(0);
}
- if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_destroy(
- &cds_ctx->qdf_conc_list_lock))) {
- cds_err("Failed to destroy qdf_conc_list_lock");
- status = QDF_STATUS_E_FAILURE;
- QDF_ASSERT(0);
- }
-
if (QDF_TIMER_STATE_RUNNING ==
qdf_mc_timer_get_current_state(
&cds_ctx->dbs_opportunistic_timer)) {
@@ -4047,13 +4136,6 @@ QDF_STATUS cds_init_policy_mgr(struct cds_sme_cbacks *sme_cbacks)
/* init conc_connection_list */
qdf_mem_zero(conc_connection_list, sizeof(conc_connection_list));
- if (!QDF_IS_STATUS_SUCCESS(qdf_mutex_create(
- &cds_ctx->qdf_conc_list_lock))) {
- cds_err("Failed to init qdf_conc_list_lock");
- /* Lets us not proceed further */
- return QDF_STATUS_E_FAILURE;
- }
-
sme_register_hw_mode_trans_cb(hdd_ctx->hHal,
cds_hw_mode_transition_cb);
status = qdf_mc_timer_init(&cds_ctx->dbs_opportunistic_timer,
@@ -4097,6 +4179,14 @@ QDF_STATUS cds_init_policy_mgr(struct cds_sme_cbacks *sme_cbacks)
static uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id)
{
uint32_t conn_index = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return conn_index;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if ((conc_connection_list[conn_index].vdev_id == vdev_id) &&
@@ -4104,6 +4194,7 @@ static uint32_t cds_get_connection_for_vdev_id(uint32_t vdev_id)
break;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return conn_index;
}
@@ -4317,9 +4408,9 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id)
}
conn_index++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
if (!found) {
/* err msg */
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
return status;
@@ -4329,7 +4420,6 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id)
if (NULL == wma_conn_table_entry) {
/* err msg*/
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("can't find vdev_id %d in WMA table", vdev_id);
return status;
}
@@ -4358,7 +4448,6 @@ QDF_STATUS cds_update_connection_info(uint32_t vdev_id)
wma_conn_table_entry->mac_id,
chain_mask,
nss, vdev_id, true);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return QDF_STATUS_SUCCESS;
}
@@ -4378,7 +4467,15 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
QDF_STATUS status = QDF_STATUS_E_FAILURE;
uint32_t conn_index = 0, next_conn_index = 0;
bool found = false;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return status;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (vdev_id == conc_connection_list[conn_index].vdev_id) {
/* debug msg */
@@ -4390,6 +4487,7 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
if (!found) {
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
next_conn_index = conn_index + 1;
@@ -4417,6 +4515,7 @@ QDF_STATUS cds_decr_connection_count(uint32_t vdev_id)
/* clean up the entry */
qdf_mem_zero(&conc_connection_list[next_conn_index - 1],
sizeof(*conc_connection_list));
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return QDF_STATUS_SUCCESS;
}
@@ -4449,6 +4548,13 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
QDF_STATUS status = QDF_STATUS_SUCCESS;
uint32_t conn_index = 0, num_channels = 0;
uint32_t weight1, weight2;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return status;
+ }
if ((NULL == channels) || (NULL == len)) {
cds_err("channels or len is NULL");
@@ -4481,6 +4587,7 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
weight2 = WEIGHT_OF_GROUP3_PCL_CHANNELS;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (CDS_PCL_ORDER_NONE == order) {
while (CONC_CONNECTION_LIST_VALID_INDEX(conn_index)) {
if (skip_dfs_channel && CDS_IS_DFS_CH(
@@ -4555,6 +4662,7 @@ QDF_STATUS cds_get_connection_channels(uint8_t *channels,
cds_err("unknown order %d", order);
status = QDF_STATUS_E_FAILURE;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -5010,6 +5118,14 @@ bool cds_map_concurrency_mode(enum tQDF_ADAPTER_MODE *old_mode,
uint8_t cds_get_channel(enum cds_con_mode mode, uint32_t *vdev_id)
{
uint32_t idx = 0;
+ uint8_t chan;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return 0;
+ }
if (mode >= CDS_MAX_NUM_OF_MODE) {
cds_err("incorrect mode");
@@ -5017,11 +5133,16 @@ uint8_t cds_get_channel(enum cds_con_mode mode, uint32_t *vdev_id)
}
for (idx = 0; idx < MAX_NUMBER_OF_CONC_CONNECTIONS; idx++) {
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if ((conc_connection_list[idx].mode == mode) &&
(!vdev_id || (*vdev_id ==
conc_connection_list[idx].vdev_id))
- && conc_connection_list[idx].in_use)
- return conc_connection_list[idx].chan;
+ && conc_connection_list[idx].in_use) {
+ chan = conc_connection_list[idx].chan;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return chan;
+ }
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
return 0;
}
@@ -5177,6 +5298,14 @@ static bool cds_disallow_mcc(uint8_t channel)
{
uint32_t index = 0;
bool match = false;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return match;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
while (CONC_CONNECTION_LIST_VALID_INDEX(index)) {
if (wma_is_hw_dbs_capable() == false) {
if (conc_connection_list[index].chan !=
@@ -5193,6 +5322,7 @@ static bool cds_disallow_mcc(uint8_t channel)
}
index++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return match;
}
@@ -5212,7 +5342,15 @@ static bool cds_allow_new_home_channel(uint8_t channel,
uint32_t num_connections)
{
bool status = true;
+ cds_context_type *cds_ctx;
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return false;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if ((num_connections == 2) &&
(conc_connection_list[0].chan != conc_connection_list[1].chan)
&&
@@ -5237,6 +5375,7 @@ static bool cds_allow_new_home_channel(uint8_t channel,
status = false;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -5256,11 +5395,19 @@ bool cds_is_ibss_conn_exist(uint8_t *ibss_channel)
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
bool status = false;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return status;
+ }
if (NULL == ibss_channel) {
cds_err("Null pointer error");
return false;
}
count = cds_mode_specific_connection_count(CDS_IBSS_MODE, list);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (count == 0) {
/* No IBSS connection */
status = false;
@@ -5272,6 +5419,7 @@ bool cds_is_ibss_conn_exist(uint8_t *ibss_channel)
cds_notice("Multiple IBSS connections, picking first one");
status = true;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -5288,7 +5436,15 @@ static bool cds_vht160_conn_exist(void)
{
uint32_t conn_index;
bool status = false;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return status;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS;
conn_index++) {
if (conc_connection_list[conn_index].in_use &&
@@ -5300,6 +5456,7 @@ static bool cds_vht160_conn_exist(void)
break;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -5322,17 +5479,27 @@ static bool cds_is_5g_channel_allowed(uint8_t channel, uint32_t *list,
enum cds_con_mode mode)
{
uint32_t index = 0, count = 0;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return false;
+ }
count = cds_mode_specific_connection_count(mode, list);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
while (index < count) {
if (CDS_IS_DFS_CH(conc_connection_list[list[index]].chan) &&
CDS_IS_CHANNEL_5GHZ(channel) &&
(channel != conc_connection_list[list[index]].chan)) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("don't allow MCC if SAP/GO on DFS channel");
return false;
}
index++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return true;
}
@@ -5373,7 +5540,6 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
return status;
}
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
qdf_mem_zero(&pcl, sizeof(pcl));
ret = cds_get_pcl(mode, pcl.pcl_list, &pcl.pcl_len,
@@ -5452,8 +5618,10 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
cds_err("No IBSS, we have concurrent connections already");
goto done;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (CDS_STA_MODE != conc_connection_list[0].mode) {
cds_err("No IBSS, we've a non-STA connection");
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
}
/*
@@ -5465,9 +5633,11 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
(conc_connection_list[0].chan != channel) &&
CDS_IS_SAME_BAND_CHANNELS(
conc_connection_list[0].chan, channel)) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("No IBSS + STA MCC");
goto done;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
} else if (num_connections) {
cds_err("No IBSS, we have one connection already");
goto done;
@@ -5488,9 +5658,11 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
cds_err("No 2nd STA, we already have IBSS concurrency");
goto done;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (channel &&
(CDS_IS_DFS_CH(conc_connection_list[0].chan))
&& (CDS_IS_CHANNEL_5GHZ(channel))) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("No IBSS + STA SCC/MCC, IBSS is on DFS channel");
goto done;
}
@@ -5503,8 +5675,10 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
CDS_IS_SAME_BAND_CHANNELS(
conc_connection_list[0].chan, channel)) {
cds_err("No IBSS + STA MCC");
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
} else {
cds_err("No STA, we have IBSS connection already");
goto done;
@@ -5516,14 +5690,17 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
index = 0;
count = cds_mode_specific_connection_count(
CDS_P2P_GO_MODE, list);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
while (index < count) {
if (CDS_IS_SAME_BAND_CHANNELS(channel,
conc_connection_list[list[index]].chan)) {
cds_err("Don't allow P2P GO on same band");
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
goto done;
}
index++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
/* don't allow concurrency on vht160 or vht 80+80 */
@@ -5543,7 +5720,6 @@ bool cds_allow_concurrency(enum cds_con_mode mode,
status = true;
done:
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -5587,7 +5763,15 @@ enum cds_conc_priority_mode cds_get_first_connection_pcl_table_index(void)
enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void)
{
enum cds_one_connection_mode index = CDS_MAX_ONE_CONNECTION_MODE;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return index;
+ }
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (CDS_STA_MODE == conc_connection_list[0].mode) {
if (CDS_IS_CHANNEL_24GHZ(conc_connection_list[0].chan)) {
if (CDS_ONE_ONE == conc_connection_list[0].chain_mask)
@@ -5654,6 +5838,7 @@ enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void)
conc_connection_list[0].mode, conc_connection_list[0].chan,
conc_connection_list[0].chain_mask, index);
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return index;
}
@@ -5672,7 +5857,15 @@ enum cds_one_connection_mode cds_get_second_connection_pcl_table_index(void)
enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void)
{
enum cds_one_connection_mode index = CDS_MAX_TWO_CONNECTION_MODE;
+ cds_context_type *cds_ctx;
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return index;
+ }
+
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
/* P2P Client + SAP */
if (((CDS_P2P_CLIENT_MODE == conc_connection_list[0].mode) &&
(CDS_SAP_MODE == conc_connection_list[1].mode)) ||
@@ -5999,6 +6192,7 @@ enum cds_two_connection_mode cds_get_third_connection_pcl_table_index(void)
conc_connection_list[0].chan, conc_connection_list[1].chan,
conc_connection_list[0].chain_mask, index);
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return index;
}
@@ -6093,7 +6287,6 @@ QDF_STATUS cds_current_connections_update(uint32_t session_id,
else
band = CDS_BAND_5;
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
num_connections = cds_get_connection_count();
cds_debug("num_connections=%d channel=%d",
@@ -6139,7 +6332,6 @@ QDF_STATUS cds_current_connections_update(uint32_t session_id,
reason, session_id);
done:
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return status;
}
@@ -6178,17 +6370,14 @@ static void cds_nss_update_cb(void *context, uint8_t tx_status, uint8_t vdev_id,
/*
* Check if we are ok to request for HW mode change now
*/
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
conn_index = cds_get_connection_for_vdev_id(vdev_id);
if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("connection not found for vdev %d", vdev_id);
return;
}
cds_debug("nss update successful for vdev:%d", vdev_id);
cds_next_actions(vdev_id, next_action, reason);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return;
}
@@ -6217,6 +6406,15 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action,
uint32_t list[MAX_NUMBER_OF_CONC_CONNECTIONS];
uint32_t conn_index = 0;
hdd_context_t *hdd_ctx;
+ uint32_t vdev_id;
+ uint32_t original_nss;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return status;
+ }
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -6237,23 +6435,25 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action,
count = cds_mode_specific_connection_count(
CDS_P2P_GO_MODE, list);
for (index = 0; index < count; index++) {
- conn_index = cds_get_connection_for_vdev_id(
- conc_connection_list[list[index]].vdev_id);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ vdev_id = conc_connection_list[list[index]].vdev_id;
+ original_nss = conc_connection_list[list[index]].original_nss;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ conn_index = cds_get_connection_for_vdev_id(vdev_id);
if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
cds_err("connection not found for vdev %d",
- conc_connection_list[list[index]].vdev_id);
+ vdev_id);
continue;
}
- if (2 == conc_connection_list[list[index]].original_nss) {
+ if (2 == original_nss) {
status = sme_nss_update_request(hdd_ctx->hHal,
- conc_connection_list
- [list[index]].vdev_id, new_nss,
+ vdev_id, new_nss,
cds_nss_update_cb,
next_action, hdd_ctx, reason);
if (!QDF_IS_STATUS_SUCCESS(status)) {
cds_err("sme_nss_update_request() failed for vdev %d",
- conc_connection_list[list[index]].vdev_id);
+ vdev_id);
}
}
}
@@ -6261,22 +6461,24 @@ static QDF_STATUS cds_complete_action(uint8_t new_nss, uint8_t next_action,
count = cds_mode_specific_connection_count(
CDS_SAP_MODE, list);
for (index = 0; index < count; index++) {
- conn_index = cds_get_connection_for_vdev_id(
- conc_connection_list[list[index]].vdev_id);
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
+ vdev_id = conc_connection_list[list[index]].vdev_id;
+ original_nss = conc_connection_list[list[index]].original_nss;
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ conn_index = cds_get_connection_for_vdev_id(vdev_id);
if (MAX_NUMBER_OF_CONC_CONNECTIONS == conn_index) {
cds_err("connection not found for vdev %d",
- conc_connection_list[list[index]].vdev_id);
+ vdev_id);
continue;
}
- if (2 == conc_connection_list[list[index]].original_nss) {
+ if (2 == original_nss) {
status = sme_nss_update_request(hdd_ctx->hHal,
- conc_connection_list
- [list[index]].vdev_id, new_nss,
+ vdev_id, new_nss,
cds_nss_update_cb,
next_action, hdd_ctx, reason);
if (!QDF_IS_STATUS_SUCCESS(status)) {
cds_err("sme_nss_update_request() failed for vdev %d",
- conc_connection_list[list[index]].vdev_id);
+ vdev_id);
}
}
}
@@ -7739,9 +7941,9 @@ QDF_STATUS cds_update_connection_info_utfw(
}
conn_index++;
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
if (!found) {
/* err msg */
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("can't find vdev_id %d in conc_connection_list",
vdev_id);
return status;
@@ -7752,7 +7954,6 @@ QDF_STATUS cds_update_connection_info_utfw(
cds_get_mode(type, sub_type),
channelid, HW_MODE_20_MHZ,
mac_id, chain_mask, 0, vdev_id, true);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return QDF_STATUS_SUCCESS;
}
@@ -7779,11 +7980,9 @@ QDF_STATUS cds_incr_connection_count_utfw(
return status;
}
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
conn_index = cds_get_connection_count();
if (MAX_NUMBER_OF_CONC_CONNECTIONS <= conn_index) {
/* err msg */
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_err("exceeded max connection limit %d",
MAX_NUMBER_OF_CONC_CONNECTIONS);
return status;
@@ -7794,7 +7993,6 @@ QDF_STATUS cds_incr_connection_count_utfw(
cds_get_mode(type, sub_type),
channelid, HW_MODE_20_MHZ,
mac_id, chain_mask, 0, vdev_id, true);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
return QDF_STATUS_SUCCESS;
}
@@ -7821,9 +8019,7 @@ QDF_STATUS cds_decr_connection_count_utfw(uint32_t del_all,
return QDF_STATUS_E_FAILURE;
}
} else {
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
cds_decr_connection_count(vdev_id);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
return QDF_STATUS_SUCCESS;
@@ -8193,6 +8389,14 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void)
struct sir_hw_mode_params hw_mode;
QDF_STATUS status;
hdd_context_t *hdd_ctx;
+ enum cds_conc_next_action next_action;
+ cds_context_type *cds_ctx;
+
+ cds_ctx = cds_get_context(QDF_MODULE_ID_QDF);
+ if (!cds_ctx) {
+ cds_err("Invalid CDS Context");
+ return CDS_NOP;
+ }
hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
if (!hdd_ctx) {
@@ -8208,6 +8412,7 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void)
num_connections = cds_get_connection_count();
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
cds_debug("chan[0]:%d chan[1]:%d chan[2]:%d num_connections:%d dbs:%d",
conc_connection_list[0].chan, conc_connection_list[1].chan,
conc_connection_list[2].chan, num_connections, hw_mode.dbs_cap);
@@ -8218,34 +8423,45 @@ static enum cds_conc_next_action cds_get_current_pref_hw_mode(void)
switch (num_connections) {
case 1:
/* The driver would already be in the required hw mode */
- return CDS_NOP;
+ next_action = CDS_NOP;
+ break;
case 2:
band1 = cds_chan_to_band(conc_connection_list[0].chan);
band2 = cds_chan_to_band(conc_connection_list[1].chan);
if ((band1 == band2) && (hw_mode.dbs_cap))
- return CDS_SINGLE_MAC_UPGRADE;
+ next_action = CDS_SINGLE_MAC_UPGRADE;
else if ((band1 != band2) && (!hw_mode.dbs_cap))
- return CDS_DBS_DOWNGRADE;
+ next_action = CDS_DBS_DOWNGRADE;
else
- return CDS_NOP;
+ next_action = CDS_NOP;
+
+ break;
case 3:
band1 = cds_chan_to_band(conc_connection_list[0].chan);
band2 = cds_chan_to_band(conc_connection_list[1].chan);
band3 = cds_chan_to_band(conc_connection_list[2].chan);
if (((band1 == band2) && (band2 == band3)) &&
- (hw_mode.dbs_cap))
- return CDS_SINGLE_MAC_UPGRADE;
- else if (((band1 != band2) || (band2 != band3) ||
- (band1 != band3)) && (!hw_mode.dbs_cap))
- return CDS_DBS_DOWNGRADE;
- else
- return CDS_NOP;
+ (hw_mode.dbs_cap)) {
+ next_action = CDS_SINGLE_MAC_UPGRADE;
+ } else if (((band1 != band2) || (band2 != band3) ||
+ (band1 != band3)) &&
+ (!hw_mode.dbs_cap)) {
+ next_action = CDS_DBS_DOWNGRADE;
+ } else {
+ next_action = CDS_NOP;
+ }
+ break;
default:
cds_err("unexpected num_connections value %d",
num_connections);
- return CDS_NOP;
+ next_action = CDS_NOP;
+ break;
}
+
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
+ return next_action;
+
}
/**
@@ -8815,7 +9031,6 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight)
qdf_mem_set(weight->weighed_valid_list, QDF_MAX_NUM_CHAN,
WEIGHT_OF_DISALLOWED_CHANNELS);
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
if (cds_mode_specific_connection_count(CDS_STA_MODE, NULL) > 0) {
/*
* Store the STA mode's parameter and temporarily delete it
@@ -8824,7 +9039,6 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight)
* allowing to detect the disallowed channels.
*/
cds_store_and_del_conn_info(CDS_STA_MODE, &info);
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
/*
* There is a small window between releasing the above lock
* and acquiring the same in cds_allow_concurrency, below!
@@ -8838,11 +9052,9 @@ QDF_STATUS cds_get_valid_chan_weights(struct sir_pcl_chan_weights *weight)
}
}
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
/* Restore the connection info */
cds_restore_deleted_conn_info(&info);
}
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
for (i = 0; i < weight->saved_num_chan; i++) {
for (j = 0; j < weight->pcl_len; j++) {
@@ -8890,8 +9102,6 @@ QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id)
return status;
}
- qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
-
action = cds_get_current_pref_hw_mode();
if ((action != CDS_DBS_DOWNGRADE) &&
@@ -8926,7 +9136,6 @@ QDF_STATUS cds_set_hw_mode_on_channel_switch(uint8_t session_id)
goto done;
}
done:
- qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
/* success must be returned only when a set hw mode was done */
return status;
}
@@ -8950,6 +9159,7 @@ void cds_dump_connection_status_info(void)
return;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
cds_debug("%d: use:%d vdev:%d mode:%d mac:%d chan:%d orig chainmask:%d orig nss:%d bw:%d",
i, conc_connection_list[i].in_use,
@@ -8961,6 +9171,7 @@ void cds_dump_connection_status_info(void)
conc_connection_list[i].original_nss,
conc_connection_list[i].bw);
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
}
/**
@@ -9160,14 +9371,17 @@ void cds_checkn_update_hw_mode_single_mac_mode(uint8_t channel)
return;
}
+ qdf_mutex_acquire(&cds_ctx->qdf_conc_list_lock);
for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) {
if (conc_connection_list[i].in_use)
if (!CDS_IS_SAME_BAND_CHANNELS(channel,
conc_connection_list[i].chan)) {
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
cds_info("DBS required");
return;
}
}
+ qdf_mutex_release(&cds_ctx->qdf_conc_list_lock);
if (QDF_TIMER_STATE_RUNNING ==
cds_ctx->dbs_opportunistic_timer.state)
diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c
index fb95d3be3e45..9c5d3bc2b7c3 100644
--- a/core/hdd/src/wlan_hdd_cfg80211.c
+++ b/core/hdd/src/wlan_hdd_cfg80211.c
@@ -6437,7 +6437,7 @@ nla_put_failure:
static int hdd_get_bpf_offload(hdd_context_t *hdd_ctx)
{
unsigned long rc;
- struct hdd_bpf_context *context;
+ static struct hdd_bpf_context *context;
QDF_STATUS status;
int ret;
diff --git a/core/hdd/src/wlan_hdd_ext_scan.c b/core/hdd/src/wlan_hdd_ext_scan.c
index 5140ad92c132..b389d4edd310 100644
--- a/core/hdd/src/wlan_hdd_ext_scan.c
+++ b/core/hdd/src/wlan_hdd_ext_scan.c
@@ -2549,6 +2549,13 @@ __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
maxChannels =
nla_get_u32(tb
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
+
+ if (maxChannels > WNI_CFG_VALID_CHANNEL_LIST_LEN) {
+ hdd_err("Max channels %d exceeded Valid channel list len %d",
+ maxChannels, WNI_CFG_VALID_CHANNEL_LIST_LEN);
+ return -EINVAL;
+ }
+
hdd_notice("Req Id: %u Wifi band: %d Max channels: %d", requestId,
wifiBand, maxChannels);
status = sme_get_valid_channels_by_band((tHalHandle) (pHddCtx->hHal),
diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c
index b12f4cba749c..683b17a8c5f3 100644
--- a/core/hdd/src/wlan_hdd_ioctl.c
+++ b/core/hdd/src/wlan_hdd_ioctl.c
@@ -198,7 +198,7 @@ QDF_STATUS hdd_get_tsm_stats(hdd_adapter_t *adapter,
QDF_STATUS hstatus;
QDF_STATUS vstatus = QDF_STATUS_SUCCESS;
unsigned long rc;
- struct statsContext context;
+ static struct statsContext context;
hdd_context_t *hdd_ctx = NULL;
if (NULL == adapter) {
@@ -2422,7 +2422,7 @@ static int wlan_hdd_get_link_status(hdd_adapter_t *adapter)
hdd_station_ctx_t *pHddStaCtx =
WLAN_HDD_GET_STATION_CTX_PTR(adapter);
- struct statsContext context;
+ static struct statsContext context;
QDF_STATUS hstatus;
unsigned long rc;
diff --git a/core/hdd/src/wlan_hdd_ipa.c b/core/hdd/src/wlan_hdd_ipa.c
index b42df3a390ea..5f4703e07178 100644
--- a/core/hdd/src/wlan_hdd_ipa.c
+++ b/core/hdd/src/wlan_hdd_ipa.c
@@ -1608,6 +1608,13 @@ static void hdd_ipa_uc_offload_enable_disable(hdd_adapter_t *adapter,
return;
}
+ if (wlan_hdd_validate_session_id(adapter->sessionId)) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "invalid session id: %d, offload_type=%d, enable=%d",
+ adapter->sessionId, offload_type, enable);
+ return;
+ }
+
qdf_mem_zero(&ipa_offload_enable_disable,
sizeof(ipa_offload_enable_disable));
ipa_offload_enable_disable.offload_type = offload_type;
@@ -1876,6 +1883,97 @@ void hdd_ipa_uc_force_pipe_shutdown(hdd_context_t *hdd_ctx)
}
/**
+ * hdd_ipa_msg_free_fn() - Free an IPA message
+ * @buff: pointer to the IPA message
+ * @len: length of the IPA message
+ * @type: type of IPA message
+ *
+ * Return: None
+ */
+static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
+{
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "msg type:%d, len:%d", type, len);
+ ghdd_ipa->stats.num_free_msg++;
+ qdf_mem_free(buff);
+}
+
+
+/**
+ * hdd_ipa_send_disconnect() - ipa send disconnect clients
+ * adapter: pointer to hdd adapter
+ * Send disconnect evnt to IPA driver during SSR
+ *
+ * Return: 0 - Success
+ */
+static int hdd_ipa_send_disconnect(hdd_adapter_t *adapter)
+{
+ struct ipa_msg_meta meta;
+ struct ipa_wlan_msg *msg;
+ int ret = 0;
+ int i;
+
+ for (i = 0; i < WLAN_MAX_STA_COUNT; i++) {
+ if (qdf_is_macaddr_broadcast(&adapter->aStaInfo[i].macAddrSTA))
+ continue;
+ if ((adapter->aStaInfo[i].isUsed) &&
+ (!adapter->aStaInfo[i].isDeauthInProgress)) {
+ meta.msg_len = sizeof(struct ipa_wlan_msg);
+ msg = qdf_mem_malloc(meta.msg_len);
+ if (msg == NULL) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "msg allocation failed");
+ return -ENOMEM;
+ }
+ meta.msg_type = WLAN_CLIENT_DISCONNECT;
+ strlcpy(msg->name, adapter->dev->name,
+ IPA_RESOURCE_NAME_MAX);
+ memcpy(msg->mac_addr, adapter->aStaInfo[i].macAddrSTA.bytes,
+ ETH_ALEN);
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d",
+ msg->name, meta.msg_type);
+ ret = ipa_send_msg(&meta, msg, hdd_ipa_msg_free_fn);
+ if (ret) {
+ HDD_IPA_LOG(QDF_TRACE_LEVEL_ERROR,
+ "%s: Evt: %d fail:%d",
+ msg->name, meta.msg_type, ret);
+ qdf_mem_free(msg);
+ return ret;
+ }
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * hdd_ipa_uc_disconnect_client() - disconnect ipa sap clients
+ * hdd_ctx: pointer to hdd context
+ * Send disconnect evnt to IPA driver during SSR
+ *
+ * Return: 0 - Success
+ */
+static int hdd_ipa_uc_disconnect_client(hdd_context_t *hdd_ctx)
+{
+ hdd_adapter_list_node_t *adapter_node = NULL, *next = NULL;
+ QDF_STATUS status;
+ hdd_adapter_t *adapter;
+ int ret = 0;
+
+
+ status = hdd_get_front_adapter(hdd_ctx, &adapter_node);
+ while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) {
+ adapter = adapter_node->pAdapter;
+ if (adapter->device_mode == QDF_SAP_MODE)
+ hdd_ipa_send_disconnect(adapter);
+ status = hdd_get_next_adapter(
+ hdd_ctx, adapter_node, &next);
+ adapter_node = next;
+ }
+
+ return ret;
+}
+
+/**
* hdd_ipa_uc_ssr_deinit() - handle ipa deinit for SSR
*
* Deinit basic IPA UC host side to be in sync reloaded FW during
@@ -1892,6 +1990,8 @@ int hdd_ipa_uc_ssr_deinit(void)
if ((!hdd_ipa) || (!hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)))
return 0;
+ /* send disconnect to ipa driver for connected clients */
+ hdd_ipa_uc_disconnect_client(hdd_ipa->hdd_ctx);
/* Clean up HDD IPA interfaces */
for (idx = 0; (hdd_ipa->num_iface > 0) &&
(idx < HDD_IPA_MAX_IFACE); idx++) {
@@ -3537,21 +3637,6 @@ end:
return ret;
}
-/**
- * hdd_ipa_msg_free_fn() - Free an IPA message
- * @buff: pointer to the IPA message
- * @len: length of the IPA message
- * @type: type of IPA message
- *
- * Return: None
- */
-static void hdd_ipa_msg_free_fn(void *buff, uint32_t len, uint32_t type)
-{
- hddLog(LOG1, "msg type:%d, len:%d", type, len);
- ghdd_ipa->stats.num_free_msg++;
- qdf_mem_free(buff);
-}
-
#ifndef QCA_LL_TX_FLOW_CONTROL_V2
/**
* hdd_ipa_send_mcc_scc_msg() - send IPA WLAN_SWITCH_TO_MCC/SCC message
@@ -3834,7 +3919,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (ret) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO,
"%s: Evt: %d, Interface setup failed",
- msg_ex->name, meta.msg_type);
+ adapter->dev->name, type);
qdf_mutex_release(&hdd_ipa->event_lock);
goto end;
}
@@ -3859,7 +3944,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (!hdd_ipa->sta_connected) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO,
"%s: Evt: %d, STA already disconnected",
- msg_ex->name, meta.msg_type);
+ adapter->dev->name, type);
qdf_mutex_release(&hdd_ipa->event_lock);
return -EINVAL;
}
@@ -3898,7 +3983,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (!adapter->ipa_context) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO,
"%s: Evt: %d, SAP already disconnected",
- msg_ex->name, meta.msg_type);
+ adapter->dev->name, type);
qdf_mutex_release(&hdd_ipa->event_lock);
return -EINVAL;
}
@@ -3938,7 +4023,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (!hdd_ipa_uc_is_enabled(hdd_ipa->hdd_ctx)) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO,
"%s: Evt: %d, IPA UC OFFLOAD NOT ENABLED",
- adapter->dev->name, meta.msg_type);
+ adapter->dev->name, type);
return 0;
}
@@ -4019,7 +4104,7 @@ static int __hdd_ipa_wlan_evt(hdd_adapter_t *adapter, uint8_t sta_id,
if (ret) {
HDD_IPA_LOG(QDF_TRACE_LEVEL_INFO, "%s: Evt: %d : %d",
- msg_ex->name, meta.msg_type, ret);
+ adapter->dev->name, type, ret);
qdf_mem_free(msg_ex);
return ret;
}
diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c
index e5c6d9f993e1..5ba5817050b0 100644
--- a/core/hdd/src/wlan_hdd_main.c
+++ b/core/hdd/src/wlan_hdd_main.c
@@ -7852,9 +7852,17 @@ int hdd_wlan_stop_modules(hdd_context_t *hdd_ctx)
goto done;
}
+ qdf_status = cds_post_disable(hdd_ctx->pcds_context);
+ if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
+ hdd_err("Failed to process post CDS disable Modules! :%d",
+ qdf_status);
+ ret = -EINVAL;
+ QDF_ASSERT(0);
+ }
qdf_status = cds_close(hdd_ctx->pcds_context);
if (!QDF_IS_STATUS_SUCCESS(qdf_status)) {
hdd_warn("Failed to stop CDS:%d", qdf_status);
+ ret = -EINVAL;
QDF_ASSERT(0);
}
/* Clean up message queues of TX, RX and MC thread */
diff --git a/core/hdd/src/wlan_hdd_memdump.c b/core/hdd/src/wlan_hdd_memdump.c
index 195d066018b2..b8765153d373 100644
--- a/core/hdd/src/wlan_hdd_memdump.c
+++ b/core/hdd/src/wlan_hdd_memdump.c
@@ -242,6 +242,8 @@ static int __wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
return -ENOMEM;
}
hdd_ctx->dump_loc_paddr = paddr;
+ } else {
+ paddr = hdd_ctx->dump_loc_paddr;
}
mutex_unlock(&hdd_ctx->memdump_lock);
diff --git a/core/hdd/src/wlan_hdd_power.c b/core/hdd/src/wlan_hdd_power.c
index 199fc4668d5b..f056d383937a 100644
--- a/core/hdd/src/wlan_hdd_power.c
+++ b/core/hdd/src/wlan_hdd_power.c
@@ -1461,6 +1461,7 @@ QDF_STATUS hdd_wlan_shutdown(void)
cds_clear_concurrent_session_count();
hdd_cleanup_scan_queue(pHddCtx);
+ hdd_ipa_uc_ssr_deinit();
hdd_reset_all_adapters(pHddCtx);
/* Flush cached rx frame queue */
@@ -1468,7 +1469,6 @@ QDF_STATUS hdd_wlan_shutdown(void)
/* De-register the HDD callbacks */
hdd_deregister_cb(pHddCtx);
- hdd_ipa_uc_ssr_deinit();
cds_sched_context = get_cds_sched_ctxt();
diff --git a/core/hdd/src/wlan_hdd_wext.c b/core/hdd/src/wlan_hdd_wext.c
index ff756b89f10b..cffa762b6476 100644
--- a/core/hdd/src/wlan_hdd_wext.c
+++ b/core/hdd/src/wlan_hdd_wext.c
@@ -1222,7 +1222,7 @@ static void hdd_get_snr_cb(int8_t snr, uint32_t staId, void *pContext)
*/
QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
{
- struct statsContext context;
+ static struct statsContext context;
hdd_context_t *pHddCtx;
hdd_station_ctx_t *pHddStaCtx;
QDF_STATUS hstatus;
@@ -1308,7 +1308,7 @@ QDF_STATUS wlan_hdd_get_rssi(hdd_adapter_t *pAdapter, int8_t *rssi_value)
*/
QDF_STATUS wlan_hdd_get_snr(hdd_adapter_t *pAdapter, int8_t *snr)
{
- struct statsContext context;
+ static struct statsContext context;
hdd_context_t *pHddCtx;
hdd_station_ctx_t *pHddStaCtx;
QDF_STATUS hstatus;
@@ -1455,7 +1455,7 @@ QDF_STATUS wlan_hdd_get_linkspeed_for_peermac(hdd_adapter_t *pAdapter,
struct qdf_mac_addr macAddress) {
QDF_STATUS status;
unsigned long rc;
- struct linkspeedContext context;
+ static struct linkspeedContext context;
tSirLinkSpeedInfo *linkspeed_req;
if (NULL == pAdapter) {
@@ -3649,7 +3649,7 @@ 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;
- struct statsContext context;
+ static struct statsContext context;
if (NULL == pAdapter) {
hdd_err("pAdapter is NULL");
@@ -5138,7 +5138,7 @@ static void hdd_get_temperature_cb(int temperature, void *pContext)
int wlan_hdd_get_temperature(hdd_adapter_t *pAdapter, int *temperature)
{
QDF_STATUS status;
- struct statsContext tempContext;
+ static struct statsContext tempContext;
unsigned long rc;
ENTER();
diff --git a/core/mac/inc/qwlan_version.h b/core/mac/inc/qwlan_version.h
index b5f90d497a4b..547c64d223e0 100644
--- a/core/mac/inc/qwlan_version.h
+++ b/core/mac/inc/qwlan_version.h
@@ -41,9 +41,9 @@
#define QWLAN_VERSION_MAJOR 5
#define QWLAN_VERSION_MINOR 1
#define QWLAN_VERSION_PATCH 0
-#define QWLAN_VERSION_EXTRA "B"
+#define QWLAN_VERSION_EXTRA "N"
#define QWLAN_VERSION_BUILD 36
-#define QWLAN_VERSIONSTR "5.1.0.36B"
+#define QWLAN_VERSIONSTR "5.1.0.36N"
#endif /* QWLAN_VERSION_H */
diff --git a/core/mac/inc/sir_mac_prot_def.h b/core/mac/inc/sir_mac_prot_def.h
index abf78f39bea7..79657e25cdca 100644
--- a/core/mac/inc/sir_mac_prot_def.h
+++ b/core/mac/inc/sir_mac_prot_def.h
@@ -455,10 +455,6 @@
#define SIR_MAC_CISCO_OUI "\x00\x40\x96"
#define SIR_MAC_CISCO_OUI_SIZE 3
-/* WFA vendor specific TPC OUI */
-#define SIR_MAC_WFA_TPC_OUI "\x00\x50\xF2\x08\x00"
-#define SIR_MAC_WFA_TPC_OUI_SIZE 5
-
/* min size of wme oui header: oui(3) + type + subtype + version */
#define SIR_MAC_OUI_WME_HDR_MIN 6
diff --git a/core/mac/src/pe/lim/lim_process_action_frame.c b/core/mac/src/pe/lim/lim_process_action_frame.c
index d2889095b1b9..d25e61e2c4f1 100644
--- a/core/mac/src/pe/lim/lim_process_action_frame.c
+++ b/core/mac/src/pe/lim/lim_process_action_frame.c
@@ -60,6 +60,8 @@
#define BA_DEFAULT_TX_BUFFER_SIZE 64
+static last_processed_msg rrm_link_action_frm;
+
/* Note: The test passes if the STAUT stops sending any frames, and no further
frames are transmitted on this channel by the station when the AP has sent
the last 6 beacons, with the channel switch information elements as seen
@@ -1406,7 +1408,7 @@ err:
qdf_mem_free(frm);
}
-static void
+static tSirRetStatus
__lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
tpPESession psessionEntry)
{
@@ -1420,7 +1422,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
frameLen = WMA_GET_RX_PAYLOAD_LEN(pRxPacketInfo);
if (psessionEntry == NULL) {
- return;
+ return eSIR_FAILURE;
}
/**Unpack the received frame */
@@ -1435,7 +1437,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
PELOG2(sir_dump_buf
(pMac, SIR_DBG_MODULE_ID, LOG2, pBody, frameLen);
)
- return;
+ return eSIR_FAILURE;
} else if (DOT11F_WARNED(nStatus)) {
lim_log(pMac, LOGW,
FL
@@ -1447,7 +1449,7 @@ __lim_process_link_measurement_req(tpAniSirGlobal pMac, uint8_t *pRxPacketInfo,
}
/* Call rrm function to handle the request. */
- rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
+ return rrm_process_link_measurement_request(pMac, pRxPacketInfo, &frm,
psessionEntry);
}
@@ -1912,9 +1914,19 @@ void lim_process_action_frame(tpAniSirGlobal mac_ctx,
session);
break;
case SIR_MAC_RRM_LINK_MEASUREMENT_REQ:
- __lim_process_link_measurement_req(mac_ctx,
+ if (!lim_is_valid_frame(
+ &rrm_link_action_frm,
+ rx_pkt_info))
+ break;
+
+ if (__lim_process_link_measurement_req(
+ mac_ctx,
(uint8_t *)rx_pkt_info,
- session);
+ session) == eSIR_SUCCESS)
+ lim_update_last_processed_frame(
+ &rrm_link_action_frm,
+ rx_pkt_info);
+
break;
case SIR_MAC_RRM_NEIGHBOR_RPT:
__lim_process_neighbor_report(mac_ctx,
diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
index 2343bdd28cb9..fcf99578396b 100644
--- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c
+++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c
@@ -1229,13 +1229,9 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
tSirMsgQ msg;
uint16_t i, len;
uint16_t addn_ie_len = 0;
- uint8_t *vendor_tpc_ie;
tSirRetStatus status, rc = eSIR_SUCCESS;
tDot11fIEExtCap extracted_extcap = {0};
bool extcap_present = true;
- uint32_t lim_11h_enable = WNI_CFG_11H_ENABLED_STADEF;
-
- wlan_cfg_get_int(pMac, WNI_CFG_11H_ENABLED, &lim_11h_enable);
if (pScanReq->uIEFieldLen) {
status = lim_strip_extcap_update_struct(pMac,
@@ -1266,10 +1262,6 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
len = sizeof(tSirScanOffloadReq) +
(pScanReq->channelList.numChannels - 1) +
pScanReq->uIEFieldLen;
- if (lim_11h_enable) {
- addn_ie_len += DOT11F_IE_WFATPC_MAX_LEN + 2;
- len += DOT11F_IE_WFATPC_MAX_LEN + 2;
- }
pScanOffloadReq = qdf_mem_malloc(len);
if (NULL == pScanOffloadReq) {
@@ -1342,30 +1334,6 @@ static QDF_STATUS lim_send_hal_start_scan_offload_req(tpAniSirGlobal pMac,
(uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
pScanReq->uIEFieldLen);
- if (lim_11h_enable) {
- tDot11fIEWFATPC wfa_tpc;
- vendor_tpc_ie = (uint8_t *) pScanOffloadReq +
- pScanOffloadReq->uIEFieldOffset +
- pScanOffloadReq->uIEFieldLen;
- populate_dot11f_wfatpc(pMac, &wfa_tpc,
- rrm_get_mgmt_tx_power(pMac, NULL), 0);
- vendor_tpc_ie[0] = DOT11F_EID_WFATPC;
- vendor_tpc_ie[1] = DOT11F_IE_WFATPC_MAX_LEN;
- qdf_mem_copy(&vendor_tpc_ie[2], SIR_MAC_WFA_TPC_OUI,
- SIR_MAC_WFA_TPC_OUI_SIZE);
- qdf_mem_copy(&vendor_tpc_ie[SIR_MAC_WFA_TPC_OUI_SIZE + 2],
- ((uint8_t *)&wfa_tpc) + 1,
- DOT11F_IE_WFATPC_MAX_LEN - SIR_MAC_WFA_TPC_OUI_SIZE);
- pScanOffloadReq->uIEFieldLen += DOT11F_IE_WFATPC_MAX_LEN + 2;
- if (pScanReq->uIEFieldLen)
- lim_strip_ie(pMac,
- (uint8_t *) pScanReq + pScanReq->uIEFieldOffset,
- &pScanReq->uIEFieldLen,
- DOT11F_EID_WFATPC, ONE_BYTE,
- SIR_MAC_WFA_TPC_OUI, SIR_MAC_WFA_TPC_OUI_SIZE,
- NULL);
- }
-
rc = wma_post_ctrl_msg(pMac, &msg);
if (rc != eSIR_SUCCESS) {
lim_log(pMac, LOGE, FL("wma_post_ctrl_msg() return failure"));
diff --git a/core/mac/src/pe/lim/lim_utils.c b/core/mac/src/pe/lim/lim_utils.c
index 0518ae8fe92d..ba731b8ff299 100644
--- a/core/mac/src/pe/lim/lim_utils.c
+++ b/core/mac/src/pe/lim/lim_utils.c
@@ -7218,3 +7218,76 @@ void lim_send_set_dtim_period(tpAniSirGlobal mac_ctx, uint8_t dtim_period,
qdf_mem_free(dtim_params);
}
}
+
+/**
+ * lim_is_valid_frame(): validate RX frame using last processed frame details
+ * to find if it is duplicate frame.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: RX packet.
+ *
+ * Frame treat as duplicate:
+ * if retry bit is set and
+ * if source address and seq number matches with the last processed frame
+ *
+ * Return: false if duplicate frame, else true.
+ */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo)
+{
+ uint16_t seq_num;
+ tpSirMacMgmtHdr pHdr;
+
+ if (!pRxPacketInfo) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid RX frame"));
+ return false;
+ }
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+
+ if (pHdr->fc.retry == 0)
+ return true;
+
+ seq_num = (((pHdr->seqControl.seqNumHi <<
+ HIGH_SEQ_NUM_OFFSET) |
+ pHdr->seqControl.seqNumLo));
+
+ if (last_processed_frm->seq_num == seq_num &&
+ qdf_mem_cmp(last_processed_frm->sa, pHdr->sa, ETH_ALEN) == 0) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Duplicate frame from "MAC_ADDRESS_STR " Seq Number %d"),
+ MAC_ADDR_ARRAY(pHdr->sa), seq_num);
+ return false;
+ }
+ return true;
+}
+
+/**
+ * lim_update_last_processed_frame(): update new processed frame info to cache.
+ *
+ * @last_processed_frm: last processed frame pointer.
+ * @pRxPacketInfo: Successfully processed RX packet.
+ *
+ * Return: None.
+ */
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo)
+{
+ uint16_t seq_num;
+ tpSirMacMgmtHdr pHdr;
+
+ if (!pRxPacketInfo) {
+ QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid RX frame"));
+ return;
+ }
+
+ pHdr = WMA_GET_RX_MAC_HEADER(pRxPacketInfo);
+ seq_num = (((pHdr->seqControl.seqNumHi <<
+ HIGH_SEQ_NUM_OFFSET) |
+ pHdr->seqControl.seqNumLo));
+
+ qdf_mem_copy(last_processed_frm->sa, pHdr->sa, ETH_ALEN);
+ last_processed_frm->seq_num = seq_num;
+}
diff --git a/core/mac/src/pe/lim/lim_utils.h b/core/mac/src/pe/lim/lim_utils.h
index 5ad6bd0921e4..5c6d26b57fa7 100644
--- a/core/mac/src/pe/lim/lim_utils.h
+++ b/core/mac/src/pe/lim/lim_utils.h
@@ -79,7 +79,16 @@ typedef union uPmfSaQueryTimerId {
} tPmfSaQueryTimerId, *tpPmfSaQueryTimerId;
#endif
+typedef struct last_processed_frame {
+ tSirMacAddr sa;
+ uint16_t seq_num;
+} last_processed_msg;
+
/* LIM utility functions */
+bool lim_is_valid_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo);
+void lim_update_last_processed_frame(last_processed_msg *last_processed_frm,
+ uint8_t *pRxPacketInfo);
void limGetBssidFromPkt(tpAniSirGlobal, uint8_t *, uint8_t *, uint32_t *);
char *lim_dot11_reason_str(uint16_t reasonCode);
char *lim_mlm_state_str(tLimMlmStates state);
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index cbb373b7f91e..741ae26eb185 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -2294,14 +2294,22 @@ QDF_STATUS sme_set_ese_roam_scan_channel_list(tHalHandle hHal,
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
- tpCsrNeighborRoamControlInfo pNeighborRoamInfo
- = &pMac->roam.neighborRoamInfo[sessionId];
- tpCsrChannelInfo curchnl_list_info
- = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+ tpCsrChannelInfo curchnl_list_info = NULL;
uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
uint8_t newChannelList[128] = { 0 };
uint8_t i = 0, j = 0;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
+ curchnl_list_info =
+ &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
+
status = sme_acquire_global_lock(&pMac->sme);
if (!QDF_IS_STATUS_SUCCESS(status)) {
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
@@ -5663,6 +5671,7 @@ QDF_STATUS sme_dhcp_start_ind(tHalHandle hHal,
sme_release_global_lock(&pMac->sme);
return QDF_STATUS_E_FAILURE;
}
+ pSession->dhcp_done = false;
pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd));
if (NULL == pMsg) {
@@ -5734,6 +5743,7 @@ QDF_STATUS sme_dhcp_stop_ind(tHalHandle hHal,
sme_release_global_lock(&pMac->sme);
return QDF_STATUS_E_FAILURE;
}
+ pSession->dhcp_done = true;
pMsg = (tAniDHCPInd *) qdf_mem_malloc(sizeof(tAniDHCPInd));
if (NULL == pMsg) {
@@ -8752,6 +8762,12 @@ QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -8765,6 +8781,7 @@ QDF_STATUS sme_update_roam_rssi_diff(tHalHandle hHal, uint8_t sessionId,
pMac->roam.configParam.RoamRssiDiff = RoamRssiDiff;
sme_release_global_lock(&pMac->sme);
}
+
if (pMac->roam.configParam.isRoamOffloadScanEnabled) {
csr_roam_offload_scan(pMac, sessionId,
ROAM_SCAN_OFFLOAD_UPDATE_CFG,
@@ -8827,6 +8844,12 @@ QDF_STATUS sme_update_wes_mode(tHalHandle hHal, bool isWESModeEnabled,
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -8863,6 +8886,13 @@ QDF_STATUS sme_set_roam_scan_control(tHalHandle hHal, uint8_t sessionId,
MTRACE(qdf_trace(QDF_MODULE_ID_SME,
TRACE_CODE_SME_RX_HDD_SET_SCANCTRL, NO_SESSION, 0));
+
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -9389,6 +9419,13 @@ QDF_STATUS sme_set_delay_before_vdev_stop(tHalHandle hal,
{
tpAniSirGlobal pMac = PMAC_STRUCT(hal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ if (session_id >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), session_id);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME,
@@ -9440,6 +9477,12 @@ QDF_STATUS sme_set_neighbor_scan_refresh_period
tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
pNeighborRoamConfig =
@@ -9553,6 +9596,12 @@ QDF_STATUS sme_update_empty_scan_refresh_period(tHalHandle hHal, uint8_t session
tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
pNeighborRoamConfig =
@@ -9601,6 +9650,12 @@ QDF_STATUS sme_set_neighbor_scan_min_chan_time(tHalHandle hHal,
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -9644,6 +9699,12 @@ QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionI
tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
pNeighborRoamConfig =
@@ -9683,6 +9744,13 @@ QDF_STATUS sme_set_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionI
uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return 0;
+ }
+
return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
minChannelScanTime;
}
@@ -9697,6 +9765,13 @@ uint16_t sme_get_neighbor_scan_min_chan_time(tHalHandle hHal, uint8_t sessionId)
uint32_t sme_get_neighbor_roam_state(tHalHandle hHal, uint8_t sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return 0;
+ }
+
return pMac->roam.neighborRoamInfo[sessionId].neighborRoamState;
}
@@ -9803,6 +9878,13 @@ uint32_t sme_get_lim_mlm_session_state(tHalHandle hHal, uint8_t sessionId)
uint16_t sme_get_neighbor_scan_max_chan_time(tHalHandle hHal, uint8_t sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return 0;
+ }
+
return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
maxChannelScanTime;
}
@@ -9827,6 +9909,12 @@ QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
tCsrNeighborRoamConfig *pNeighborRoamConfig = NULL;
tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
pNeighborRoamConfig =
@@ -9867,6 +9955,13 @@ QDF_STATUS sme_set_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId,
uint16_t sme_get_neighbor_scan_period(tHalHandle hHal, uint8_t sessionId)
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
+
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return 0;
+ }
+
return pMac->roam.neighborRoamInfo[sessionId].cfgParams.
neighborScanPeriod;
}
@@ -9904,14 +9999,19 @@ QDF_STATUS sme_change_roam_scan_channel_list(tHalHandle hHal, uint8_t sessionId,
{
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
- tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
- &pMac->roam.neighborRoamInfo[sessionId];
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
uint8_t oldChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
uint8_t newChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN * 2] = { 0 };
uint8_t i = 0, j = 0;
tCsrChannelInfo *chan_info;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+ pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
status = sme_acquire_global_lock(&pMac->sme);
if (!QDF_IS_STATUS_SUCCESS(status)) {
if (pMac->roam.configParam.isRoamOffloadScanEnabled)
@@ -9980,10 +10080,16 @@ QDF_STATUS sme_get_roam_scan_channel_list(tHalHandle hHal,
int i = 0;
uint8_t *pOutPtr = pChannelList;
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
- tpCsrNeighborRoamControlInfo pNeighborRoamInfo =
- &pMac->roam.neighborRoamInfo[sessionId];
+ tpCsrNeighborRoamControlInfo pNeighborRoamInfo = NULL;
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
+ pNeighborRoamInfo = &pMac->roam.neighborRoamInfo[sessionId];
status = sme_acquire_global_lock(&pMac->sme);
if (!QDF_IS_STATUS_SUCCESS(status))
return status;
@@ -13093,6 +13199,12 @@ QDF_STATUS sme_update_dfs_scan_mode(tHalHandle hHal, uint8_t sessionId,
tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
QDF_STATUS status = QDF_STATUS_SUCCESS;
+ if (sessionId >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), sessionId);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&pMac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
@@ -15671,6 +15783,12 @@ QDF_STATUS sme_update_roam_scan_hi_rssi_scan_params(tHalHandle hal_handle,
tpCsrNeighborRoamControlInfo nr_info = NULL;
uint32_t reason = 0;
+ if (session_id >= CSR_ROAM_SESSION_MAX) {
+ QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
+ FL("Invalid sme session id: %d"), session_id);
+ return QDF_STATUS_E_INVAL;
+ }
+
status = sme_acquire_global_lock(&mac_ctx->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
nr_config = &mac_ctx->roam.configParam.neighborRoamConfig;
diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c
index 2f412bd5de34..9f74eca9186d 100644
--- a/core/sme/src/csr/csr_api_roam.c
+++ b/core/sme/src/csr/csr_api_roam.c
@@ -7619,8 +7619,6 @@ QDF_STATUS csr_roam_connect(tpAniSirGlobal pMac, uint32_t sessionId,
sme_bss_type_to_string(pProfile->BSSType),
pProfile->BSSType, pProfile->AuthType.authType[0],
pProfile->EncryptionType.encryptionType[0]);
- /* Reset dhcp_done for the fresh connection */
- pSession->dhcp_done = false;
csr_roam_cancel_roaming(pMac, sessionId);
csr_scan_remove_fresh_scan_command(pMac, sessionId);
csr_scan_abort_all_scans(pMac, eCSR_SCAN_ABORT_DEFAULT);
diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c
index 8f8a4d9d1c0e..0b2f12ed87d5 100644
--- a/core/wma/src/wma_data.c
+++ b/core/wma/src/wma_data.c
@@ -1165,10 +1165,10 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
{
ol_txrx_pdev_handle pdev;
ol_txrx_vdev_handle vdev;
- ol_txrx_peer_handle peer;
- uint8_t vdev_id, peer_id;
+ uint8_t vdev_id;
bool roam_synch_in_progress = false;
QDF_STATUS status;
+ struct wma_target_req *msg;
params->status = true;
WMA_LOGD("%s: state %d selfmac %pM", __func__,
@@ -1215,16 +1215,28 @@ void wma_set_linkstate(tp_wma_handle wma, tpLinkStateParams params)
ol_txrx_vdev_pause(wma->interfaces[vdev_id].handle,
OL_TXQ_PAUSE_REASON_VDEV_STOP);
wma->interfaces[vdev_id].pause_bitmap |= (1 << PAUSE_TYPE_HOST);
- if (wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id)) {
- WMA_LOGP("%s: %d Failed to send vdev stop",
- __func__, __LINE__);
+
+ msg = wma_fill_vdev_req(wma, vdev_id,
+ WMA_SET_LINK_STATE,
+ WMA_TARGET_REQ_TYPE_VDEV_STOP, params,
+ WMA_VDEV_STOP_REQUEST_TIMEOUT);
+ if (!msg) {
+ WMA_LOGP(FL("Failed to fill vdev request for vdev_id %d"),
+ vdev_id);
+ status = QDF_STATUS_E_NOMEM;
}
- peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);
- if (peer) {
- WMA_LOGP("%s: Deleting peer %pM vdev id %d",
- __func__, params->bssid, vdev_id);
- wma_remove_peer(wma, params->bssid, vdev_id, peer,
- roam_synch_in_progress);
+ if (wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id)) {
+ WMA_LOGP("%s: %d Failed to send vdev stop vdev %d",
+ __func__, __LINE__, vdev_id);
+ } else {
+ WMA_LOGP("%s: %d vdev stop sent vdev %d",
+ __func__, __LINE__, vdev_id);
+ /*
+ * Remove peer, Vdev down and sending set link
+ * response will be handled in vdev stop response
+ * handler
+ */
+ return;
}
}
out:
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 138958cf6a0d..ed4b923d9e64 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -1499,6 +1499,24 @@ int wma_vdev_stop_resp_handler(void *handle, uint8_t *cmd_param_info,
resp_event->vdev_id);
wma_vdev_detach(wma, iface->del_staself_req, 1);
}
+ } else if (req_msg->msg_type == WMA_SET_LINK_STATE) {
+ tpLinkStateParams params =
+ (tpLinkStateParams) req_msg->user_data;
+
+ peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);
+ if (peer) {
+ WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
+ params->bssid, req_msg->vdev_id);
+ wma_remove_peer(wma, params->bssid, req_msg->vdev_id,
+ peer, false);
+ }
+ if (wmi_unified_vdev_down_send(wma->wmi_handle,
+ req_msg->vdev_id) !=
+ QDF_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+ req_msg->vdev_id);
+ }
+ wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
}
free_req_msg:
qdf_mc_timer_destroy(&req_msg->event_timeout);
@@ -2596,6 +2614,27 @@ void wma_vdev_resp_timer(void *data)
} else if (tgt_req->msg_type == WMA_HIDDEN_SSID_VDEV_RESTART) {
WMA_LOGE("Hidden ssid vdev restart Timed Out; vdev_id: %d, type = %d",
tgt_req->vdev_id, tgt_req->type);
+ } else if (tgt_req->msg_type == WMA_SET_LINK_STATE) {
+ tpLinkStateParams params =
+ (tpLinkStateParams) tgt_req->user_data;
+
+ peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id);
+ if (peer) {
+ WMA_LOGP(FL("Deleting peer %pM vdev id %d"),
+ params->bssid, tgt_req->vdev_id);
+ wma_remove_peer(wma, params->bssid, tgt_req->vdev_id,
+ peer, false);
+ }
+ if (wmi_unified_vdev_down_send(wma->wmi_handle,
+ tgt_req->vdev_id) !=
+ QDF_STATUS_SUCCESS) {
+ WMA_LOGE("Failed to send vdev down cmd: vdev %d",
+ tgt_req->vdev_id);
+ }
+ params->status = QDF_STATUS_E_TIMEOUT;
+ WMA_LOGA("%s: WMA_SET_LINK_STATE timedout vdev %d", __func__,
+ tgt_req->vdev_id);
+ wma_send_msg(wma, WMA_SET_LINK_STATE_RSP, (void *)params, 0);
}
free_tgt_req:
qdf_mc_timer_destroy(&tgt_req->event_timeout);
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 8db6b3b52926..91e4fc6be238 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -3191,19 +3191,6 @@ QDF_STATUS wma_stop(void *cds_ctx, uint8_t reason)
WMA_LOGE("Failed to destroy the log completion timer");
}
- /* There's no need suspend target which is already down during SSR. */
- if (!cds_is_driver_recovering()) {
-#ifdef HIF_USB
- /* Suspend the target and enable interrupt */
- if (wma_suspend_target(wma_handle, 0))
- WMA_LOGE("Failed to suspend target");
-#else
- /* Suspend the target and disable interrupt */
- if (wma_suspend_target(wma_handle, 1))
- WMA_LOGE("Failed to suspend target");
-#endif /* HIF_USB */
- }
-
/* clean up ll-queue for all vdev */
for (i = 0; i < wma_handle->max_bssid; i++) {
if (wma_handle->interfaces[i].handle &&
diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c
index f5273850f7dd..37a242410b46 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -1696,6 +1696,10 @@ int wma_stats_event_handler(void *handle, uint8_t *cmd_param_info,
if (rssi_event->num_per_chain_rssi_stats > 0) {
temp = (uint8_t *) rssi_event;
temp += sizeof(*rssi_event);
+
+ /* skip past struct array tlv header */
+ temp += WMI_TLV_HDR_SIZE;
+
for (i = 0;
i < rssi_event->num_per_chain_rssi_stats;
i++) {