diff --git a/net/bluetooth/hci_sync.c b/net/bluetooth/hci_sync.c
index e6d804b82b67..cb0c219ebe1c 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -4649,6 +4649,9 @@ int hci_stop_discovery_sync(struct hci_dev *hdev)
 	if (use_ll_privacy(hdev))
 		hci_resume_advertising_sync(hdev);
 
+	/* Sampling Period is disabled while active scanning, re-enable it */
+	msft_set_active_scan(hdev, false);
+
 	/* No further actions needed for LE-only discovery */
 	if (d->type == DISCOV_TYPE_LE)
 		return 0;
@@ -5139,6 +5142,9 @@ int hci_start_discovery_sync(struct hci_dev *hdev)
 	if (err)
 		return err;
 
+	/* Disable Sampling Period while active scanning */
+	msft_set_active_scan(hdev, true);
+
 	bt_dev_dbg(hdev, "timeout %u ms", jiffies_to_msecs(timeout));
 
 	/* When service discovery is used and the controller has a
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index bee6a4c656be..f63c911b210c 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -101,6 +101,7 @@ struct msft_data {
 	struct list_head handle_map;
 	__u8 resuming;
 	__u8 suspending;
+	__u8 active_scan;
 	__u8 filter_enabled;
 };
 
@@ -333,14 +334,14 @@ static int msft_remove_monitor_sync(struct hci_dev *hdev,
 }
 
 /* This function requires the caller holds hci_req_sync_lock */
-int msft_suspend_sync(struct hci_dev *hdev)
+static void remove_all_monitors(struct hci_dev *hdev)
 {
 	struct msft_data *msft = hdev->msft_data;
 	struct adv_monitor *monitor;
 	int handle = 0;
 
 	if (!msft || !msft_monitor_supported(hdev))
-		return 0;
+		return;
 
 	msft->suspending = true;
 
@@ -356,6 +357,12 @@ int msft_suspend_sync(struct hci_dev *hdev)
 
 	/* All monitors have been removed */
 	msft->suspending = false;
+}
+
+/* This function requires the caller holds hci_req_sync_lock */
+int msft_suspend_sync(struct hci_dev *hdev)
+{
+	remove_all_monitors(hdev);
 
 	return 0;
 }
@@ -392,6 +399,7 @@ static bool msft_monitor_pattern_valid(struct adv_monitor *monitor)
 static int msft_add_monitor_sync(struct hci_dev *hdev,
 				 struct adv_monitor *monitor)
 {
+	struct msft_data *msft = hdev->msft_data;
 	struct msft_cp_le_monitor_advertisement *cp;
 	struct msft_le_monitor_advertisement_pattern_data *pattern_data;
 	struct msft_le_monitor_advertisement_pattern *pattern;
@@ -417,7 +425,16 @@ static int msft_add_monitor_sync(struct hci_dev *hdev,
 	cp->rssi_high = monitor->rssi.high_threshold;
 	cp->rssi_low = monitor->rssi.low_threshold;
 	cp->rssi_low_interval = (u8)monitor->rssi.low_threshold_timeout;
-	cp->rssi_sampling_period = monitor->rssi.sampling_period;
+
+	/* Some controllers apply Sampling Period even while active scanning.
+	 * So, to keep the behavior consistent across all controllers, don't
+	 * use Sampling Period during active scanning to force the controller
+	 * to report all advertisements even if it matches the monitor.
+	 */
+	if (msft->active_scan)
+		cp->rssi_sampling_period = 0;
+	else
+		cp->rssi_sampling_period = monitor->rssi.sampling_period;
 
 	cp->cond_type = MSFT_MONITOR_ADVERTISEMENT_TYPE_PATTERN;
 
@@ -815,6 +832,28 @@ void msft_req_add_set_filter_enable(struct hci_request *req, bool enable)
 	hci_req_add(req, hdev->msft_opcode, sizeof(cp), &cp);
 }
 
+/* This function requires the caller holds hci_req_sync_lock */
+void msft_set_active_scan(struct hci_dev *hdev, bool enable)
+{
+	struct msft_data *msft = hdev->msft_data;
+
+	if (!msft)
+		return;
+
+	/* Remove all monitors */
+	remove_all_monitors(hdev);
+
+	/* Clear all tracked devices */
+	hci_dev_lock(hdev);
+	hdev->advmon_pend_notify = false;
+	msft_monitor_device_del(hdev, 0, NULL, 0, true);
+	hci_dev_unlock(hdev);
+
+	/* Update active scan and reregister all monitors */
+	msft->active_scan = enable;
+	reregister_monitor(hdev);
+}
+
 int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
 {
 	struct hci_request req;
diff --git a/net/bluetooth/msft.h b/net/bluetooth/msft.h
index 2a63205b377b..7dfd866dacc4 100644
--- a/net/bluetooth/msft.h
+++ b/net/bluetooth/msft.h
@@ -22,6 +22,7 @@ __u64 msft_get_features(struct hci_dev *hdev);
 int msft_add_monitor_pattern(struct hci_dev *hdev, struct adv_monitor *monitor);
 int msft_remove_monitor(struct hci_dev *hdev, struct adv_monitor *monitor);
 void msft_req_add_set_filter_enable(struct hci_request *req, bool enable);
+void msft_set_active_scan(struct hci_dev *hdev, bool enable);
 int msft_set_filter_enable(struct hci_dev *hdev, bool enable);
 int msft_suspend_sync(struct hci_dev *hdev);
 int msft_resume_sync(struct hci_dev *hdev);
@@ -55,6 +56,7 @@ static inline int msft_remove_monitor(struct hci_dev *hdev,
 
 static inline void msft_req_add_set_filter_enable(struct hci_request *req,
 						  bool enable) {}
+static inline void msft_set_active_scan(struct hci_dev *hdev, bool enable) {}
 static inline int msft_set_filter_enable(struct hci_dev *hdev, bool enable)
 {
 	return -EOPNOTSUPP;
