Преглед на файлове

qcacmn: In restart case invoke regulatory callbacks only once

Currently driver invokes regulatory callbacks after pdev create
and from reg cc event processing. In case of restart of the
driver because of SSR or idle restart, driver ignores the default
country and sets the user set country which was there before SSR
or idle shutdown. Now driver continues restart and creates pdev.
During pdev creation it propagates reg rules from psoc to pdev
which was there in psoc before shutdown and after pdev creation
it invokes the regulatory callbacks, as part of this hdd dynamic
callback is invoked and it tries to schedule the regulatory work.
Since idle restart is a vdev operation so driver is not able to
schedule the work as it does not get the dsc op and it waits for
500 ms to reschedule the work. In this 500ms time driver gets the
response of the set country command which was sent to fw to set
user country. This command also invokes the hdd dynamic callback
and regulatory work gets scheduled and scan channel list command
is sent to fw.
Now if any scan is going on in the FW and after 500ms if first
work gets rescheduled, it again sends the scan channel list to fw
which cancels the ongoing scan.

To address issue, add a change to not invoke regulatory callbacks
from pdev creation if user country set is pending.

Change-Id: I5686163644409ef19507c19ae31f7f1e7892931f
CRs-Fixed: 3054603
Ashish Kumar Dhanotiya преди 3 години
родител
ревизия
91dbd69b0e
променени са 1 файла, в които са добавени 46 реда и са изтрити 0 реда
  1. 46 0
      umac/regulatory/dispatcher/src/wlan_reg_services_api.c

+ 46 - 0
umac/regulatory/dispatcher/src/wlan_reg_services_api.c

@@ -486,6 +486,49 @@ QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc)
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef CONFIG_REG_CLIENT
+/**
+ * reg_is_cntry_set_pending() - Check if country set is pending
+ * @pdev: Pointer to pdev object.
+ * @psoc: Pointer to psoc object.
+ */
+static bool reg_is_cntry_set_pending(struct wlan_objmgr_pdev *pdev,
+				     struct wlan_objmgr_psoc *psoc)
+{
+	struct wlan_regulatory_psoc_priv_obj *soc_reg;
+	struct wlan_lmac_if_reg_tx_ops *tx_ops;
+	uint8_t phy_id;
+
+	soc_reg = reg_get_psoc_obj(psoc);
+
+	if (!IS_VALID_PSOC_REG_OBJ(soc_reg)) {
+		reg_err("psoc reg component is NULL");
+		return false;
+	}
+
+	tx_ops = reg_get_psoc_tx_ops(psoc);
+
+	if (tx_ops->get_phy_id_from_pdev_id)
+		tx_ops->get_phy_id_from_pdev_id(
+					psoc,
+					wlan_objmgr_pdev_get_pdev_id(pdev),
+					&phy_id);
+	else
+		phy_id = wlan_objmgr_pdev_get_pdev_id(pdev);
+
+	return (soc_reg->new_user_ctry_pending[phy_id] ||
+		soc_reg->new_init_ctry_pending[phy_id] ||
+		soc_reg->new_11d_ctry_pending[phy_id] ||
+		soc_reg->world_country_pending[phy_id]);
+}
+#else
+static inline bool reg_is_cntry_set_pending(struct wlan_objmgr_pdev *pdev,
+					    struct wlan_objmgr_psoc *psoc)
+{
+	return false;
+}
+#endif
+
 QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev)
 {
 	struct wlan_objmgr_psoc *parent_psoc;
@@ -502,6 +545,9 @@ QDF_STATUS regulatory_pdev_open(struct wlan_objmgr_pdev *pdev)
 
 	parent_psoc = wlan_pdev_get_psoc(pdev);
 
+	if (reg_is_cntry_set_pending(pdev, parent_psoc))
+		return QDF_STATUS_SUCCESS;
+
 	reg_send_scheduler_msg_nb(parent_psoc, pdev);
 
 	return QDF_STATUS_SUCCESS;