static void hci_req_start_scan(struct hci_request *req, u8 type, u16 interval,
                               u16 window, u8 own_addr_type, u8 filter_policy,
-                              bool addr_resolv)
+                              bool filter_dup, bool addr_resolv)
 {
        struct hci_dev *hdev = req->hdev;
 
 
                memset(&ext_enable_cp, 0, sizeof(ext_enable_cp));
                ext_enable_cp.enable = LE_SCAN_ENABLE;
-               ext_enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
+               ext_enable_cp.filter_dup = filter_dup;
 
                hci_req_add(req, HCI_OP_LE_SET_EXT_SCAN_ENABLE,
                            sizeof(ext_enable_cp), &ext_enable_cp);
 
                memset(&enable_cp, 0, sizeof(enable_cp));
                enable_cp.enable = LE_SCAN_ENABLE;
-               enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
+               enable_cp.filter_dup = filter_dup;
                hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
                            &enable_cp);
        }
        u8 own_addr_type;
        u8 filter_policy;
        u16 window, interval;
+       /* Default is to enable duplicates filter */
+       u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
        /* Background scanning should run with address resolution */
        bool addr_resolv = true;
 
        } else if (hci_is_adv_monitoring(hdev)) {
                window = hdev->le_scan_window_adv_monitor;
                interval = hdev->le_scan_int_adv_monitor;
+
+               /* Disable duplicates filter when scanning for advertisement
+                * monitor for the following reasons.
+                *
+                * For HW pattern filtering (ex. MSFT), Realtek and Qualcomm
+                * controllers ignore RSSI_Sampling_Period when the duplicates
+                * filter is enabled.
+                *
+                * For SW pattern filtering, when we're not doing interleaved
+                * scanning, it is necessary to disable duplicates filter,
+                * otherwise hosts can only receive one advertisement and it's
+                * impossible to know if a peer is still in range.
+                */
+               filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
        } else {
                window = hdev->le_scan_window;
                interval = hdev->le_scan_interval;
 
        bt_dev_dbg(hdev, "LE passive scan with whitelist = %d", filter_policy);
        hci_req_start_scan(req, LE_SCAN_PASSIVE, interval, window,
-                          own_addr_type, filter_policy, addr_resolv);
+                          own_addr_type, filter_policy, filter_dup,
+                          addr_resolv);
 }
 
 static bool adv_instance_is_scannable(struct hci_dev *hdev, u8 instance)
        u8 own_addr_type;
        /* White list is not used for discovery */
        u8 filter_policy = 0x00;
+       /* Default is to enable duplicates filter */
+       u8 filter_dup = LE_SCAN_FILTER_DUP_ENABLE;
        /* Discovery doesn't require controller address resolution */
        bool addr_resolv = false;
        int err;
        if (err < 0)
                own_addr_type = ADDR_LE_DEV_PUBLIC;
 
+       if (hci_is_adv_monitoring(hdev)) {
+               /* Duplicate filter should be disabled when some advertisement
+                * monitor is activated, otherwise AdvMon can only receive one
+                * advertisement for one peer(*) during active scanning, and
+                * might report loss to these peers.
+                *
+                * Note that different controllers have different meanings of
+                * |duplicate|. Some of them consider packets with the same
+                * address as duplicate, and others consider packets with the
+                * same address and the same RSSI as duplicate. Although in the
+                * latter case we don't need to disable duplicate filter, but
+                * it is common to have active scanning for a short period of
+                * time, the power impact should be neglectable.
+                */
+               filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
+       }
+
        hci_req_start_scan(req, LE_SCAN_ACTIVE, interval,
                           hdev->le_scan_window_discovery, own_addr_type,
-                          filter_policy, addr_resolv);
+                          filter_policy, filter_dup, addr_resolv);
        return 0;
 }