summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAditya Kodukula <quic_akodukul@quicinc.com>2020-03-20 16:38:18 +0530
committerPaul Chen <chenpaul@google.com>2022-06-16 05:51:54 +0000
commit8e54eec6e8cd7ca6e1344b03110879d9e9ba10ca (patch)
treec5c7f326a8670cf5b59069c907ce7f9b18bf3396
parent64b2f90b3c80a9f62daea7ec417497440e28aab2 (diff)
downloadqca-wfi-host-cmn-8e54eec6e8cd7ca6e1344b03110879d9e9ba10ca.tar.gz
Currently whenever host gets an indication for the cc event list, it starts 11d machine and inside 11d state machine, it decides that whether host needs to send start 11d scan command to fw or stop 11d scan command to fw, based on that it updates the enable_11d_supp variable of regulatory psoc private object and posts the message to scheduler. FW expects that host should not send back to back 11d start scan command, there should be one 11d stop scan command before next 11d start scan command is sent if already one 11d start scan command is sent. Host 11d state machine takes care of the above sequence of 11d scan command by using enable_11d_supp. 11d state machine sets enable_11d_supp whenever 11d scan start command needs to be sent and resets enable_11d_supp whenever 11d scan stop command needs to be sent and posts the message in the scheduler. There is a case where if host receives the 11d cc event from FW it sends the set country command to FW and at the same time if user command comes to set the country, host again sends the set country command to FW. FW processes both of these commands and sends the cc list event to host. when host receives cc events it starts the 11d machine. For the first cc event which is for 11d country which is processed as user country because of incorrect logic in reg process master channel list where it is assumed that at a time only one type of country set command can be pending and first priority is given to the user country pending, host resets enable_11d_supp and post the command to scheduler. When host receives the cc list event for the user country it is processed as 11d country and inside 11d state machine it sets enable_11d_supp and posts the command to scheduler. Now if scheduler schedules these commands it treats both the commands as start 11d scan commands as enable_11d_supp is set and sends start 11d scan command back to back. To avoid above issue, add enable_11d_supp also as part of the scheduler msg body pointer along with the psoc, in she scheduler callback use this local variable to decide whether 11d start scan needs to be sent or 11d stop scan needs to be sent. Change-Id: I60150da1475251a1c22778a0f924bdfbe1bb1140 CRs-Fixed: 2641803 Bug: 232204808 Signed-off-by: Aditya Kodukula <quic_akodukul@quicinc.com>
-rw-r--r--umac/regulatory/core/src/reg_services.c45
-rw-r--r--umac/regulatory/dispatcher/inc/reg_services_public_struct.h10
2 files changed, 42 insertions, 13 deletions
diff --git a/umac/regulatory/core/src/reg_services.c b/umac/regulatory/core/src/reg_services.c
index 533eb80f7..f8c761edf 100644
--- a/umac/regulatory/core/src/reg_services.c
+++ b/umac/regulatory/core/src/reg_services.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020 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
@@ -2983,16 +2983,19 @@ static QDF_STATUS reg_send_scheduler_msg_nb(struct wlan_objmgr_psoc *psoc,
static QDF_STATUS reg_send_11d_flush_cbk(struct scheduler_msg *msg)
{
- struct wlan_objmgr_psoc *psoc = msg->bodyptr;
+ struct reg_11d_scan_msg *scan_msg_11d = msg->bodyptr;
+ struct wlan_objmgr_psoc *psoc = scan_msg_11d->psoc;
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
+ qdf_mem_free(scan_msg_11d);
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS reg_send_11d_msg_cbk(struct scheduler_msg *msg)
{
- struct wlan_objmgr_psoc *psoc = msg->bodyptr;
+ struct reg_11d_scan_msg *scan_msg_11d = msg->bodyptr;
+ struct wlan_objmgr_psoc *psoc = scan_msg_11d->psoc;
struct wlan_lmac_if_reg_tx_ops *tx_ops;
struct reg_start_11d_scan_req start_req;
struct reg_stop_11d_scan_req stop_req;
@@ -3014,7 +3017,7 @@ static QDF_STATUS reg_send_11d_msg_cbk(struct scheduler_msg *msg)
goto end;
}
- if (psoc_priv_obj->enable_11d_supp) {
+ if (scan_msg_11d->enable_11d_supp) {
start_req.vdev_id = psoc_priv_obj->vdev_id_for_11d_scan;
start_req.scan_period_msec = psoc_priv_obj->scan_11d_interval;
start_req.start_interval_msec = 0;
@@ -3027,32 +3030,33 @@ static QDF_STATUS reg_send_11d_msg_cbk(struct scheduler_msg *msg)
}
end:
+ qdf_mem_free(scan_msg_11d);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
return QDF_STATUS_SUCCESS;
}
-static QDF_STATUS reg_sched_11d_msg(struct wlan_objmgr_psoc *psoc)
+static QDF_STATUS reg_sched_11d_msg(struct reg_11d_scan_msg *scan_msg_11d)
{
struct scheduler_msg msg = {0};
QDF_STATUS status;
- status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
+ status = wlan_objmgr_psoc_try_get_ref(scan_msg_11d->psoc,
+ WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
- msg.bodyptr = psoc;
+ msg.bodyptr = scan_msg_11d;
msg.callback = reg_send_11d_msg_cbk;
msg.flush_callback = reg_send_11d_flush_cbk;
status = scheduler_post_message(QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_TARGET_IF, &msg);
- if (QDF_IS_STATUS_ERROR(status)) {
- wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
- reg_err("scheduler msg posting failed");
- }
+ if (QDF_IS_STATUS_ERROR(status))
+ wlan_objmgr_psoc_release_ref(scan_msg_11d->psoc,
+ WLAN_REGULATORY_SB_ID);
return status;
}
@@ -3163,6 +3167,7 @@ static void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc)
bool temp_11d_support;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
bool world_mode;
+ struct reg_11d_scan_msg *scan_msg_11d;
psoc_priv_obj = wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_REGULATORY);
@@ -3190,10 +3195,24 @@ static void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc)
psoc_priv_obj->enable_11d_supp =
psoc_priv_obj->enable_11d_supp_original;
- reg_debug("inside 11d state machine");
+ reg_debug("inside 11d state machine:tmp %d 11d_supp %d org %d set %d pri %d cnt %d vdev %d",
+ temp_11d_support,
+ psoc_priv_obj->enable_11d_supp,
+ psoc_priv_obj->enable_11d_supp_original,
+ psoc_priv_obj->user_ctry_set,
+ psoc_priv_obj->user_ctry_priority,
+ psoc_priv_obj->master_vdev_cnt,
+ psoc_priv_obj->vdev_id_for_11d_scan);
+
if ((temp_11d_support != psoc_priv_obj->enable_11d_supp) &&
(psoc_priv_obj->is_11d_offloaded)) {
- reg_sched_11d_msg(psoc);
+ scan_msg_11d = qdf_mem_malloc(sizeof(*scan_msg_11d));
+ if (!scan_msg_11d)
+ return;
+ scan_msg_11d->psoc = psoc;
+ scan_msg_11d->enable_11d_supp =
+ psoc_priv_obj->enable_11d_supp;
+ reg_sched_11d_msg(scan_msg_11d);
}
}
diff --git a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h
index 5a598a396..b4d6e4a5c 100644
--- a/umac/regulatory/dispatcher/inc/reg_services_public_struct.h
+++ b/umac/regulatory/dispatcher/inc/reg_services_public_struct.h
@@ -612,6 +612,16 @@ struct reg_start_11d_scan_req {
};
/**
+ * struct reg_11d_scan_msg: 11d scan message structure
+ * @psoc: pointer to psoc object
+ * @enable_11d_supp: enable 11d scan or disable 11d scan
+ */
+struct reg_11d_scan_msg {
+ struct wlan_objmgr_psoc *psoc;
+ bool enable_11d_supp;
+};
+
+/**
* struct reg_stop_11d_scan_req: stop 11d scan request
* @vdev_id: vdev id
*/