#define HCI_LE_SLAVE_FEATURES          0x08
 #define HCI_LE_PING                    0x10
 #define HCI_LE_DATA_LEN_EXT            0x20
+#define HCI_LE_PHY_2M                  0x01
+#define HCI_LE_PHY_CODED               0x08
 #define HCI_LE_EXT_ADV                 0x10
 #define HCI_LE_EXT_SCAN_POLICY         0x80
 #define HCI_LE_PHY_2M                  0x01
 } __packed;
 
 #define HCI_ADV_PHY_1M         0X01
+#define HCI_ADV_PHY_2M         0x02
+#define HCI_ADV_PHY_CODED      0x03
 
 struct hci_rp_le_set_ext_adv_params {
        __u8  status;
 
 #define MGMT_ADV_FLAG_TX_POWER         BIT(4)
 #define MGMT_ADV_FLAG_APPEARANCE       BIT(5)
 #define MGMT_ADV_FLAG_LOCAL_NAME       BIT(6)
+#define MGMT_ADV_FLAG_SEC_1M           BIT(7)
+#define MGMT_ADV_FLAG_SEC_2M           BIT(8)
+#define MGMT_ADV_FLAG_SEC_CODED        BIT(9)
+
+#define MGMT_ADV_FLAG_SEC_MASK (MGMT_ADV_FLAG_SEC_1M | MGMT_ADV_FLAG_SEC_2M | \
+                                MGMT_ADV_FLAG_SEC_CODED)
 
 #define MGMT_OP_REMOVE_ADVERTISING     0x003F
 struct mgmt_cp_remove_advertising {
 
        u8 own_addr_type;
        int err;
        struct adv_info *adv_instance;
+       bool secondary_adv;
        /* In ext adv set param interval is 3 octets */
        const u8 adv_interval[3] = { 0x00, 0x08, 0x00 };
 
        memcpy(cp.min_interval, adv_interval, sizeof(cp.min_interval));
        memcpy(cp.max_interval, adv_interval, sizeof(cp.max_interval));
 
-       if (connectable)
-               cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND);
-       else if (get_adv_instance_scan_rsp_len(hdev, instance))
-               cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_SCAN_IND);
-       else
-               cp.evt_properties = cpu_to_le16(LE_LEGACY_NONCONN_IND);
+       secondary_adv = (flags & MGMT_ADV_FLAG_SEC_MASK);
+
+       if (connectable) {
+               if (secondary_adv)
+                       cp.evt_properties = cpu_to_le16(LE_EXT_ADV_CONN_IND);
+               else
+                       cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_IND);
+       } else if (get_adv_instance_scan_rsp_len(hdev, instance)) {
+               if (secondary_adv)
+                       cp.evt_properties = cpu_to_le16(LE_EXT_ADV_SCAN_IND);
+               else
+                       cp.evt_properties = cpu_to_le16(LE_LEGACY_ADV_SCAN_IND);
+       } else {
+               if (secondary_adv)
+                       cp.evt_properties = cpu_to_le16(LE_EXT_ADV_NON_CONN_IND);
+               else
+                       cp.evt_properties = cpu_to_le16(LE_LEGACY_NONCONN_IND);
+       }
 
        cp.own_addr_type = own_addr_type;
        cp.channel_map = hdev->le_adv_channel_map;
        cp.tx_power = 127;
-       cp.primary_phy = HCI_ADV_PHY_1M;
-       cp.secondary_phy = HCI_ADV_PHY_1M;
        cp.handle = 0;
 
+       if (flags & MGMT_ADV_FLAG_SEC_2M) {
+               cp.primary_phy = HCI_ADV_PHY_1M;
+               cp.secondary_phy = HCI_ADV_PHY_2M;
+       } else if (flags & MGMT_ADV_FLAG_SEC_CODED) {
+               cp.primary_phy = HCI_ADV_PHY_CODED;
+               cp.secondary_phy = HCI_ADV_PHY_CODED;
+       } else {
+               /* In all other cases use 1M */
+               cp.primary_phy = HCI_ADV_PHY_1M;
+               cp.secondary_phy = HCI_ADV_PHY_1M;
+       }
+
        hci_req_add(req, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(cp), &cp);
 
        if (own_addr_type == ADDR_LE_DEV_RANDOM &&
 
            ext_adv_capable(hdev))
                flags |= MGMT_ADV_FLAG_TX_POWER;
 
+       if (ext_adv_capable(hdev)) {
+               flags |= MGMT_ADV_FLAG_SEC_1M;
+
+               if (hdev->le_features[1] & HCI_LE_PHY_2M)
+                       flags |= MGMT_ADV_FLAG_SEC_2M;
+
+               if (hdev->le_features[1] & HCI_LE_PHY_CODED)
+                       flags |= MGMT_ADV_FLAG_SEC_CODED;
+       }
+
        return flags;
 }
 
        struct mgmt_cp_add_advertising *cp = data;
        struct mgmt_rp_add_advertising rp;
        u32 flags;
-       u32 supported_flags;
+       u32 supported_flags, phy_flags;
        u8 status;
        u16 timeout, duration;
        unsigned int prev_instance_cnt = hdev->adv_instance_cnt;
        duration = __le16_to_cpu(cp->duration);
 
        /* The current implementation only supports a subset of the specified
-        * flags.
+        * flags. Also need to check mutual exclusiveness of sec flags.
         */
        supported_flags = get_supported_adv_flags(hdev);
-       if (flags & ~supported_flags)
+       phy_flags = flags & MGMT_ADV_FLAG_SEC_MASK;
+       if (flags & ~supported_flags ||
+           ((phy_flags && (phy_flags ^ (phy_flags & -phy_flags)))))
                return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
                                       MGMT_STATUS_INVALID_PARAMS);