Commit 180a2c54 authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2016-03-12

Here's the last bluetooth-next pull request for the 4.6 kernel.

 - New USB ID for AR3012 in btusb
 - New BCM2E55 ACPI ID
 - Buffer overflow fix for the Add Advertising command
 - Support for a new Bluetooth LE limited privacy mode
 - Fix for firmware activation in btmrvl_sdio
 - Cleanups to mac802154 & 6lowpan code

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f7f58ae0 6a0e7807
...@@ -120,6 +120,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -120,6 +120,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3423) }, { USB_DEVICE(0x13d3, 0x3423) },
{ USB_DEVICE(0x13d3, 0x3432) }, { USB_DEVICE(0x13d3, 0x3432) },
{ USB_DEVICE(0x13d3, 0x3472) },
{ USB_DEVICE(0x13d3, 0x3474) }, { USB_DEVICE(0x13d3, 0x3474) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
...@@ -185,6 +186,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -185,6 +186,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */
......
...@@ -371,7 +371,7 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card, ...@@ -371,7 +371,7 @@ static int btmrvl_sdio_verify_fw_download(struct btmrvl_sdio_card *card,
if (firmwarestat == FIRMWARE_READY) if (firmwarestat == FIRMWARE_READY)
return 0; return 0;
msleep(10); msleep(100);
} }
return -ETIMEDOUT; return -ETIMEDOUT;
......
...@@ -234,6 +234,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -234,6 +234,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
......
...@@ -821,6 +821,7 @@ static const struct acpi_device_id bcm_acpi_match[] = { ...@@ -821,6 +821,7 @@ static const struct acpi_device_id bcm_acpi_match[] = {
{ "BCM2E3F", 0 }, { "BCM2E3F", 0 },
{ "BCM2E40", 0 }, { "BCM2E40", 0 },
{ "BCM2E54", 0 }, { "BCM2E54", 0 },
{ "BCM2E55", 0 },
{ "BCM2E64", 0 }, { "BCM2E64", 0 },
{ "BCM2E65", 0 }, { "BCM2E65", 0 },
{ "BCM2E67", 0 }, { "BCM2E67", 0 },
......
...@@ -233,6 +233,7 @@ enum { ...@@ -233,6 +233,7 @@ enum {
HCI_SC_ENABLED, HCI_SC_ENABLED,
HCI_SC_ONLY, HCI_SC_ONLY,
HCI_PRIVACY, HCI_PRIVACY,
HCI_LIMITED_PRIVACY,
HCI_RPA_EXPIRED, HCI_RPA_EXPIRED,
HCI_RPA_RESOLVING, HCI_RPA_RESOLVING,
HCI_HS_ENABLED, HCI_HS_ENABLED,
......
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
#ifndef NET_MAC802154_H #ifndef NET_MAC802154_H
#define NET_MAC802154_H #define NET_MAC802154_H
#include <asm/unaligned.h>
#include <net/af_ieee802154.h> #include <net/af_ieee802154.h>
#include <linux/ieee802154.h> #include <linux/ieee802154.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/unaligned/memmove.h>
#include <net/cfg802154.h> #include <net/cfg802154.h>
...@@ -254,7 +254,7 @@ static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb) ...@@ -254,7 +254,7 @@ static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
return cpu_to_le16(0); return cpu_to_le16(0);
} }
return (__force __le16)__get_unaligned_memmove16(skb_mac_header(skb)); return get_unaligned_le16(skb_mac_header(skb));
} }
/** /**
...@@ -264,7 +264,7 @@ static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb) ...@@ -264,7 +264,7 @@ static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb)
*/ */
static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src) static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src)
{ {
__put_unaligned_memmove64(swab64p(be64_src), le64_dst); put_unaligned_le64(get_unaligned_be64(be64_src), le64_dst);
} }
/** /**
...@@ -274,7 +274,7 @@ static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src) ...@@ -274,7 +274,7 @@ static inline void ieee802154_be64_to_le64(void *le64_dst, const void *be64_src)
*/ */
static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
{ {
__put_unaligned_memmove64(swab64p(le64_src), be64_dst); put_unaligned_be64(get_unaligned_le64(le64_src), be64_dst);
} }
/** /**
...@@ -284,7 +284,7 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) ...@@ -284,7 +284,7 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src)
*/ */
static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src) static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src)
{ {
__put_unaligned_memmove16(swab16p(le16_src), be16_dst); put_unaligned_be16(get_unaligned_le16(le16_src), be16_dst);
} }
/** /**
......
...@@ -161,7 +161,7 @@ static ssize_t lowpan_ctx_pfx_write(struct file *fp, ...@@ -161,7 +161,7 @@ static ssize_t lowpan_ctx_pfx_write(struct file *fp,
return status; return status;
} }
const struct file_operations lowpan_ctx_pfx_fops = { static const struct file_operations lowpan_ctx_pfx_fops = {
.open = lowpan_ctx_pfx_open, .open = lowpan_ctx_pfx_open,
.read = seq_read, .read = seq_read,
.write = lowpan_ctx_pfx_write, .write = lowpan_ctx_pfx_write,
...@@ -238,7 +238,7 @@ static int lowpan_context_open(struct inode *inode, struct file *file) ...@@ -238,7 +238,7 @@ static int lowpan_context_open(struct inode *inode, struct file *file)
return single_open(file, lowpan_context_show, inode->i_private); return single_open(file, lowpan_context_show, inode->i_private);
} }
const struct file_operations lowpan_context_fops = { static const struct file_operations lowpan_context_fops = {
.open = lowpan_context_open, .open = lowpan_context_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
......
...@@ -788,7 +788,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct in6_addr *ipaddr, ...@@ -788,7 +788,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct in6_addr *ipaddr,
} }
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
/* check for SAM/DAM = 01 */ /* check for SAM/DAM = 10 */
tmp.s6_addr[11] = 0xFF; tmp.s6_addr[11] = 0xFF;
tmp.s6_addr[12] = 0xFE; tmp.s6_addr[12] = 0xFE;
memcpy(&tmp.s6_addr[14], &ipaddr->s6_addr[14], 2); memcpy(&tmp.s6_addr[14], &ipaddr->s6_addr[14], 2);
...@@ -801,7 +801,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct in6_addr *ipaddr, ...@@ -801,7 +801,7 @@ static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct in6_addr *ipaddr,
} }
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
/* check for SAM/DAM = 10, should always match */ /* check for SAM/DAM = 01, should always match */
memcpy(&tmp.s6_addr[8], &ipaddr->s6_addr[8], 8); memcpy(&tmp.s6_addr[8], &ipaddr->s6_addr[8], 8);
/* context information are always used */ /* context information are always used */
ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen); ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
......
...@@ -719,6 +719,13 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode) ...@@ -719,6 +719,13 @@ static void create_le_conn_complete(struct hci_dev *hdev, u8 status, u16 opcode)
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
static bool conn_use_rpa(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
return hci_dev_test_flag(hdev, HCI_PRIVACY);
}
static void hci_req_add_le_create_conn(struct hci_request *req, static void hci_req_add_le_create_conn(struct hci_request *req,
struct hci_conn *conn) struct hci_conn *conn)
{ {
...@@ -726,14 +733,15 @@ static void hci_req_add_le_create_conn(struct hci_request *req, ...@@ -726,14 +733,15 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
struct hci_dev *hdev = conn->hdev; struct hci_dev *hdev = conn->hdev;
u8 own_addr_type; u8 own_addr_type;
memset(&cp, 0, sizeof(cp));
/* Update random address, but set require_privacy to false so /* Update random address, but set require_privacy to false so
* that we never connect with an non-resolvable address. * that we never connect with an non-resolvable address.
*/ */
if (hci_update_random_address(req, false, &own_addr_type)) if (hci_update_random_address(req, false, conn_use_rpa(conn),
&own_addr_type))
return; return;
memset(&cp, 0, sizeof(cp));
/* Set window to be the same value as the interval to enable /* Set window to be the same value as the interval to enable
* continuous scanning. * continuous scanning.
*/ */
...@@ -774,7 +782,8 @@ static void hci_req_directed_advertising(struct hci_request *req, ...@@ -774,7 +782,8 @@ static void hci_req_directed_advertising(struct hci_request *req,
/* Set require_privacy to false so that the remote device has a /* Set require_privacy to false so that the remote device has a
* chance of identifying us. * chance of identifying us.
*/ */
if (hci_update_random_address(req, false, &own_addr_type) < 0) if (hci_update_random_address(req, false, conn_use_rpa(conn),
&own_addr_type) < 0)
return; return;
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
......
...@@ -771,6 +771,11 @@ static u8 update_white_list(struct hci_request *req) ...@@ -771,6 +771,11 @@ static u8 update_white_list(struct hci_request *req)
return 0x01; return 0x01;
} }
static bool scan_use_rpa(struct hci_dev *hdev)
{
return hci_dev_test_flag(hdev, HCI_PRIVACY);
}
void hci_req_add_le_passive_scan(struct hci_request *req) void hci_req_add_le_passive_scan(struct hci_request *req)
{ {
struct hci_cp_le_set_scan_param param_cp; struct hci_cp_le_set_scan_param param_cp;
...@@ -785,7 +790,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req) ...@@ -785,7 +790,8 @@ void hci_req_add_le_passive_scan(struct hci_request *req)
* advertising with our address will be correctly reported * advertising with our address will be correctly reported
* by the controller. * by the controller.
*/ */
if (hci_update_random_address(req, false, &own_addr_type)) if (hci_update_random_address(req, false, scan_use_rpa(hdev),
&own_addr_type))
return; return;
/* Adding or removing entries from the white list must /* Adding or removing entries from the white list must
...@@ -866,6 +872,11 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance) ...@@ -866,6 +872,11 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE)) if (hci_dev_test_flag(hdev, HCI_ADVERTISING_CONNECTABLE))
flags |= MGMT_ADV_FLAG_CONNECTABLE; flags |= MGMT_ADV_FLAG_CONNECTABLE;
if (hci_dev_test_flag(hdev, HCI_LIMITED_DISCOVERABLE))
flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
else if (hci_dev_test_flag(hdev, HCI_DISCOVERABLE))
flags |= MGMT_ADV_FLAG_DISCOV;
return flags; return flags;
} }
...@@ -878,6 +889,29 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance) ...@@ -878,6 +889,29 @@ static u32 get_adv_instance_flags(struct hci_dev *hdev, u8 instance)
return adv_instance->flags; return adv_instance->flags;
} }
static bool adv_use_rpa(struct hci_dev *hdev, uint32_t flags)
{
/* If privacy is not enabled don't use RPA */
if (!hci_dev_test_flag(hdev, HCI_PRIVACY))
return false;
/* If basic privacy mode is enabled use RPA */
if (!hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
return true;
/* If limited privacy mode is enabled don't use RPA if we're
* both discoverable and bondable.
*/
if ((flags & MGMT_ADV_FLAG_DISCOV) &&
hci_dev_test_flag(hdev, HCI_BONDABLE))
return false;
/* We're neither bondable nor discoverable in the limited
* privacy mode, therefore use RPA.
*/
return true;
}
void __hci_req_enable_advertising(struct hci_request *req) void __hci_req_enable_advertising(struct hci_request *req)
{ {
struct hci_dev *hdev = req->hdev; struct hci_dev *hdev = req->hdev;
...@@ -911,7 +945,9 @@ void __hci_req_enable_advertising(struct hci_request *req) ...@@ -911,7 +945,9 @@ void __hci_req_enable_advertising(struct hci_request *req)
* advertising is used. In that case it is fine to use a * advertising is used. In that case it is fine to use a
* non-resolvable private address. * non-resolvable private address.
*/ */
if (hci_update_random_address(req, !connectable, &own_addr_type) < 0) if (hci_update_random_address(req, !connectable,
adv_use_rpa(hdev, flags),
&own_addr_type) < 0)
return; return;
memset(&cp, 0, sizeof(cp)); memset(&cp, 0, sizeof(cp));
...@@ -1325,7 +1361,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) ...@@ -1325,7 +1361,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa)
} }
int hci_update_random_address(struct hci_request *req, bool require_privacy, int hci_update_random_address(struct hci_request *req, bool require_privacy,
u8 *own_addr_type) bool use_rpa, u8 *own_addr_type)
{ {
struct hci_dev *hdev = req->hdev; struct hci_dev *hdev = req->hdev;
int err; int err;
...@@ -1334,7 +1370,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy, ...@@ -1334,7 +1370,7 @@ int hci_update_random_address(struct hci_request *req, bool require_privacy,
* current RPA has expired or there is something else than * current RPA has expired or there is something else than
* the current RPA in use, then generate a new one. * the current RPA in use, then generate a new one.
*/ */
if (hci_dev_test_flag(hdev, HCI_PRIVACY)) { if (use_rpa) {
int to; int to;
*own_addr_type = ADDR_LE_DEV_RANDOM; *own_addr_type = ADDR_LE_DEV_RANDOM;
...@@ -1596,9 +1632,16 @@ static int discoverable_update(struct hci_request *req, unsigned long opt) ...@@ -1596,9 +1632,16 @@ static int discoverable_update(struct hci_request *req, unsigned long opt)
/* Advertising instances don't use the global discoverable setting, so /* Advertising instances don't use the global discoverable setting, so
* only update AD if advertising was enabled using Set Advertising. * only update AD if advertising was enabled using Set Advertising.
*/ */
if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) if (hci_dev_test_flag(hdev, HCI_ADVERTISING)) {
__hci_req_update_adv_data(req, 0x00); __hci_req_update_adv_data(req, 0x00);
/* Discoverable mode affects the local advertising
* address in limited privacy mode.
*/
if (hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
__hci_req_enable_advertising(req);
}
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
return 0; return 0;
...@@ -1941,7 +1984,8 @@ static int active_scan(struct hci_request *req, unsigned long opt) ...@@ -1941,7 +1984,8 @@ static int active_scan(struct hci_request *req, unsigned long opt)
* address (when privacy feature has been enabled) or non-resolvable * address (when privacy feature has been enabled) or non-resolvable
* private address. * private address.
*/ */
err = hci_update_random_address(req, true, &own_addr_type); err = hci_update_random_address(req, true, scan_use_rpa(hdev),
&own_addr_type);
if (err < 0) if (err < 0)
own_addr_type = ADDR_LE_DEV_PUBLIC; own_addr_type = ADDR_LE_DEV_PUBLIC;
......
...@@ -89,7 +89,7 @@ static inline void hci_req_update_scan(struct hci_dev *hdev) ...@@ -89,7 +89,7 @@ static inline void hci_req_update_scan(struct hci_dev *hdev)
void __hci_req_update_scan(struct hci_request *req); void __hci_req_update_scan(struct hci_request *req);
int hci_update_random_address(struct hci_request *req, bool require_privacy, int hci_update_random_address(struct hci_request *req, bool require_privacy,
u8 *own_addr_type); bool use_rpa, u8 *own_addr_type);
int hci_abort_conn(struct hci_conn *conn, u8 reason); int hci_abort_conn(struct hci_conn *conn, u8 reason);
void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn, void __hci_abort_conn(struct hci_request *req, struct hci_conn *conn,
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include "mgmt_util.h" #include "mgmt_util.h"
#define MGMT_VERSION 1 #define MGMT_VERSION 1
#define MGMT_REVISION 11 #define MGMT_REVISION 12
static const u16 mgmt_commands[] = { static const u16 mgmt_commands[] = {
MGMT_OP_READ_INDEX_LIST, MGMT_OP_READ_INDEX_LIST,
...@@ -1382,8 +1382,19 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1382,8 +1382,19 @@ static int set_bondable(struct sock *sk, struct hci_dev *hdev, void *data,
if (err < 0) if (err < 0)
goto unlock; goto unlock;
if (changed) if (changed) {
/* In limited privacy mode the change of bondable mode
* may affect the local advertising address.
*/
if (hdev_is_powered(hdev) &&
hci_dev_test_flag(hdev, HCI_ADVERTISING) &&
hci_dev_test_flag(hdev, HCI_DISCOVERABLE) &&
hci_dev_test_flag(hdev, HCI_LIMITED_PRIVACY))
queue_work(hdev->req_workqueue,
&hdev->discoverable_update);
err = new_settings(hdev, sk); err = new_settings(hdev, sk);
}
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -4423,7 +4434,7 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, ...@@ -4423,7 +4434,7 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
MGMT_STATUS_NOT_SUPPORTED); MGMT_STATUS_NOT_SUPPORTED);
if (cp->privacy != 0x00 && cp->privacy != 0x01) if (cp->privacy != 0x00 && cp->privacy != 0x01 && cp->privacy != 0x02)
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_PRIVACY,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
...@@ -4442,10 +4453,15 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data, ...@@ -4442,10 +4453,15 @@ static int set_privacy(struct sock *sk, struct hci_dev *hdev, void *cp_data,
changed = !hci_dev_test_and_set_flag(hdev, HCI_PRIVACY); changed = !hci_dev_test_and_set_flag(hdev, HCI_PRIVACY);
memcpy(hdev->irk, cp->irk, sizeof(hdev->irk)); memcpy(hdev->irk, cp->irk, sizeof(hdev->irk));
hci_dev_set_flag(hdev, HCI_RPA_EXPIRED); hci_dev_set_flag(hdev, HCI_RPA_EXPIRED);
if (cp->privacy == 0x02)
hci_dev_set_flag(hdev, HCI_LIMITED_PRIVACY);
else
hci_dev_clear_flag(hdev, HCI_LIMITED_PRIVACY);
} else { } else {
changed = hci_dev_test_and_clear_flag(hdev, HCI_PRIVACY); changed = hci_dev_test_and_clear_flag(hdev, HCI_PRIVACY);
memset(hdev->irk, 0, sizeof(hdev->irk)); memset(hdev->irk, 0, sizeof(hdev->irk));
hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED); hci_dev_clear_flag(hdev, HCI_RPA_EXPIRED);
hci_dev_clear_flag(hdev, HCI_LIMITED_PRIVACY);
} }
err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev); err = send_settings_rsp(sk, MGMT_OP_SET_PRIVACY, hdev);
...@@ -5979,6 +5995,10 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev, ...@@ -5979,6 +5995,10 @@ static int add_advertising(struct sock *sk, struct hci_dev *hdev,
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING, return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
MGMT_STATUS_INVALID_PARAMS); MGMT_STATUS_INVALID_PARAMS);
if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len)
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_ADVERTISING,
MGMT_STATUS_INVALID_PARAMS);
flags = __le32_to_cpu(cp->flags); flags = __le32_to_cpu(cp->flags);
timeout = __le16_to_cpu(cp->timeout); timeout = __le16_to_cpu(cp->timeout);
duration = __le16_to_cpu(cp->duration); duration = __le16_to_cpu(cp->duration);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment