Skip to content

Commit

Permalink
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
Here's another set of Bluetooth & ieee802154 patches intended for 4.1:

 - Added support for QCA ROME chipset family in the btusb driver
 - at86rf230 driver fixes & cleanups
 - ieee802154 cleanups
 - Refactoring of Bluetooth mgmt API to allow new users
 - New setting for static Bluetooth address exposed to user space
 - Refactoring of hci_dev flags to remove limit of 32
 - Remove unnecessary fast-connectable setting usage restrictions
 - Fix behavior to be consistent when trying to pair already paired device
 - Service discovery corner-case fixes

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
davem330 committed Mar 14, 2015
2 parents 2801be4 + b6d595e commit 5f1764d
Show file tree
Hide file tree
Showing 23 changed files with 1,888 additions and 1,386 deletions.
333 changes: 301 additions & 32 deletions drivers/bluetooth/btusb.c

Large diffs are not rendered by default.

226 changes: 154 additions & 72 deletions drivers/net/ieee802154/at86rf230.c

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions include/linux/ieee802154.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#define IEEE802154_MTU 127
#define IEEE802154_ACK_PSDU_LEN 5
#define IEEE802154_MIN_PSDU_LEN 9
#define IEEE802154_FCS_LEN 2

#define IEEE802154_PAN_ID_BROADCAST 0xffff
#define IEEE802154_ADDR_SHORT_BROADCAST 0xffff
Expand All @@ -39,6 +40,7 @@

#define IEEE802154_LIFS_PERIOD 40
#define IEEE802154_SIFS_PERIOD 12
#define IEEE802154_MAX_SIFS_FRAME_SIZE 18

#define IEEE802154_MAX_CHANNEL 26
#define IEEE802154_MAX_PAGE 31
Expand Down
3 changes: 3 additions & 0 deletions include/net/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ void l2cap_exit(void);
int sco_init(void);
void sco_exit(void);

int mgmt_init(void);
void mgmt_exit(void);

void bt_sock_reclassify_lock(struct sock *sk, int proto);

#endif /* __BLUETOOTH_H */
22 changes: 7 additions & 15 deletions include/net/bluetooth/hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,15 +179,6 @@ enum {
HCI_RESET,
};

/* BR/EDR and/or LE controller flags: the flags defined here should represent
* states configured via debugfs for debugging and testing purposes only.
*/
enum {
HCI_DUT_MODE,
HCI_FORCE_BREDR_SMP,
HCI_FORCE_STATIC_ADDR,
};

/*
* BR/EDR and/or LE controller flags: the flags defined here should represent
* states from the controller.
Expand Down Expand Up @@ -217,6 +208,7 @@ enum {
HCI_HS_ENABLED,
HCI_LE_ENABLED,
HCI_ADVERTISING,
HCI_ADVERTISING_CONNECTABLE,
HCI_CONNECTABLE,
HCI_DISCOVERABLE,
HCI_LIMITED_DISCOVERABLE,
Expand All @@ -225,13 +217,13 @@ enum {
HCI_FAST_CONNECTABLE,
HCI_BREDR_ENABLED,
HCI_LE_SCAN_INTERRUPTED,
};

/* A mask for the flags that are supposed to remain when a reset happens
* or the HCI device is closed.
*/
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV))
HCI_DUT_MODE,
HCI_FORCE_BREDR_SMP,
HCI_FORCE_STATIC_ADDR,

__HCI_NUM_FLAGS,
};

/* HCI timeouts */
#define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
Expand Down
59 changes: 50 additions & 9 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ struct discovery_state {
u8 last_adv_data[HCI_MAX_AD_LENGTH];
u8 last_adv_data_len;
bool report_invalid_rssi;
bool result_filtering;
s8 rssi;
u16 uuid_count;
u8 (*uuids)[16];
Expand Down Expand Up @@ -352,8 +353,7 @@ struct hci_dev {

struct rfkill *rfkill;

unsigned long dbg_flags;
unsigned long dev_flags;
DECLARE_BITMAP(dev_flags, __HCI_NUM_FLAGS);

struct delayed_work le_scan_disable;
struct delayed_work le_scan_restart;
Expand Down Expand Up @@ -501,6 +501,21 @@ extern struct list_head hci_cb_list;
extern rwlock_t hci_dev_list_lock;
extern struct mutex hci_cb_list_lock;

#define hci_dev_set_flag(hdev, nr) set_bit((nr), (hdev)->dev_flags)
#define hci_dev_clear_flag(hdev, nr) clear_bit((nr), (hdev)->dev_flags)
#define hci_dev_change_flag(hdev, nr) change_bit((nr), (hdev)->dev_flags)
#define hci_dev_test_flag(hdev, nr) test_bit((nr), (hdev)->dev_flags)
#define hci_dev_test_and_set_flag(hdev, nr) test_and_set_bit((nr), (hdev)->dev_flags)
#define hci_dev_test_and_clear_flag(hdev, nr) test_and_clear_bit((nr), (hdev)->dev_flags)
#define hci_dev_test_and_change_flag(hdev, nr) test_and_change_bit((nr), (hdev)->dev_flags)

#define hci_dev_clear_volatile_flags(hdev) \
do { \
hci_dev_clear_flag(hdev, HCI_LE_SCAN); \
hci_dev_clear_flag(hdev, HCI_LE_ADV); \
hci_dev_clear_flag(hdev, HCI_PERIODIC_INQ); \
} while (0)

/* ----- HCI interface to upper protocols ----- */
int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr);
int l2cap_disconn_ind(struct hci_conn *hcon);
Expand All @@ -525,6 +540,7 @@ static inline void discovery_init(struct hci_dev *hdev)

static inline void hci_discovery_filter_clear(struct hci_dev *hdev)
{
hdev->discovery.result_filtering = false;
hdev->discovery.report_invalid_rssi = true;
hdev->discovery.rssi = HCI_RSSI_INVALID;
hdev->discovery.uuid_count = 0;
Expand Down Expand Up @@ -596,14 +612,14 @@ enum {
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
return test_bit(HCI_SSP_ENABLED, &hdev->dev_flags) &&
return hci_dev_test_flag(hdev, HCI_SSP_ENABLED) &&
test_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
}

static inline bool hci_conn_sc_enabled(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
return test_bit(HCI_SC_ENABLED, &hdev->dev_flags) &&
return hci_dev_test_flag(hdev, HCI_SC_ENABLED) &&
test_bit(HCI_CONN_SC_ENABLED, &conn->flags);
}

Expand Down Expand Up @@ -965,6 +981,8 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr,
void hci_remove_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type);
void hci_smp_irks_clear(struct hci_dev *hdev);

bool hci_bdaddr_is_paired(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);

void hci_remote_oob_data_clear(struct hci_dev *hdev);
struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 bdaddr_type);
Expand Down Expand Up @@ -1021,10 +1039,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
#define lmp_host_le_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE))
#define lmp_host_le_br_capable(dev) (!!((dev)->features[1][0] & LMP_HOST_LE_BREDR))

#define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \
!test_bit(HCI_AUTO_OFF, &hdev->dev_flags))
#define bredr_sc_enabled(dev) (lmp_sc_capable(dev) && \
test_bit(HCI_SC_ENABLED, &(dev)->dev_flags))
#define hdev_is_powered(dev) (test_bit(HCI_UP, &(dev)->flags) && \
!hci_dev_test_flag(dev, HCI_AUTO_OFF))
#define bredr_sc_enabled(dev) (lmp_sc_capable(dev) && \
hci_dev_test_flag(dev, HCI_SC_ENABLED))

/* ----- HCI protocols ----- */
#define HCI_PROTO_DEFER 0x01
Expand Down Expand Up @@ -1271,6 +1289,27 @@ void hci_send_to_monitor(struct hci_dev *hdev, struct sk_buff *skb);

void hci_sock_dev_event(struct hci_dev *hdev, int event);

#define HCI_MGMT_VAR_LEN (1 << 0)
#define HCI_MGMT_NO_HDEV (1 << 1)
#define HCI_MGMT_UNCONFIGURED (1 << 2)

struct hci_mgmt_handler {
int (*func) (struct sock *sk, struct hci_dev *hdev, void *data,
u16 data_len);
size_t data_len;
unsigned long flags;
};

struct hci_mgmt_chan {
struct list_head list;
unsigned short channel;
size_t handler_count;
const struct hci_mgmt_handler *handlers;
};

int hci_mgmt_chan_register(struct hci_mgmt_chan *c);
void hci_mgmt_chan_unregister(struct hci_mgmt_chan *c);

/* Management interface */
#define DISCOV_TYPE_BREDR (BIT(BDADDR_BREDR))
#define DISCOV_TYPE_LE (BIT(BDADDR_LE_PUBLIC) | \
Expand All @@ -1290,7 +1329,9 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_BREDR_INQUIRY_LEN 0x08
#define DISCOV_LE_RESTART_DELAY msecs_to_jiffies(200) /* msec */

int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
int mgmt_control(struct hci_mgmt_chan *chan, struct sock *sk,
struct msghdr *msg, size_t msglen);

int mgmt_new_settings(struct hci_dev *hdev);
void mgmt_index_added(struct hci_dev *hdev);
void mgmt_index_removed(struct hci_dev *hdev);
Expand Down
2 changes: 2 additions & 0 deletions include/net/bluetooth/mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define MGMT_STATUS_CANCELLED 0x10
#define MGMT_STATUS_INVALID_INDEX 0x11
#define MGMT_STATUS_RFKILLED 0x12
#define MGMT_STATUS_ALREADY_PAIRED 0x13

struct mgmt_hdr {
__le16 opcode;
Expand Down Expand Up @@ -98,6 +99,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_DEBUG_KEYS 0x00001000
#define MGMT_SETTING_PRIVACY 0x00002000
#define MGMT_SETTING_CONFIGURATION 0x00004000
#define MGMT_SETTING_STATIC_ADDRESS 0x00008000

#define MGMT_OP_READ_INFO 0x0004
#define MGMT_READ_INFO_SIZE 0
Expand Down
9 changes: 9 additions & 0 deletions net/bluetooth/af_bluetooth.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,13 @@ static int __init bt_init(void)
goto sock_err;
}

err = mgmt_init();
if (err < 0) {
sco_exit();
l2cap_exit();
goto sock_err;
}

return 0;

sock_err:
Expand All @@ -763,6 +770,8 @@ static int __init bt_init(void)

static void __exit bt_exit(void)
{
mgmt_exit();

sco_exit();

l2cap_exit();
Expand Down
18 changes: 9 additions & 9 deletions net/bluetooth/hci_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)

list_for_each_entry(d, &hci_dev_list, list) {
if (!test_bit(HCI_UP, &d->flags) ||
test_bit(HCI_USER_CHANNEL, &d->dev_flags) ||
hci_dev_test_flag(d, HCI_USER_CHANNEL) ||
d->dev_type != HCI_BREDR)
continue;

Expand Down Expand Up @@ -700,7 +700,7 @@ static void hci_req_directed_advertising(struct hci_request *req,
* and write a new random address. The flag will be set back on
* as soon as the SET_ADV_ENABLE HCI command completes.
*/
clear_bit(HCI_LE_ADV, &hdev->dev_flags);
hci_dev_clear_flag(hdev, HCI_LE_ADV);

/* Set require_privacy to false so that the remote device has a
* chance of identifying us.
Expand Down Expand Up @@ -734,7 +734,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
int err;

/* Let's make sure that le is enabled.*/
if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED)) {
if (lmp_le_capable(hdev))
return ERR_PTR(-ECONNREFUSED);

Expand Down Expand Up @@ -799,7 +799,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
* anyway have to disable it in order to start directed
* advertising.
*/
if (test_bit(HCI_LE_ADV, &hdev->dev_flags)) {
if (hci_dev_test_flag(hdev, HCI_LE_ADV)) {
u8 enable = 0x00;
hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable),
&enable);
Expand All @@ -810,7 +810,7 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
/* If we're active scanning most controllers are unable
* to initiate advertising. Simply reject the attempt.
*/
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags) &&
if (hci_dev_test_flag(hdev, HCI_LE_SCAN) &&
hdev->le_scan_type == LE_SCAN_ACTIVE) {
skb_queue_purge(&req.cmd_q);
hci_conn_del(conn);
Expand Down Expand Up @@ -840,9 +840,9 @@ struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
* handler for scan disabling knows to set the correct discovery
* state.
*/
if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) {
if (hci_dev_test_flag(hdev, HCI_LE_SCAN)) {
hci_req_add_le_scan_disable(&req);
set_bit(HCI_LE_SCAN_INTERRUPTED, &hdev->dev_flags);
hci_dev_set_flag(hdev, HCI_LE_SCAN_INTERRUPTED);
}

hci_req_add_le_create_conn(&req, conn);
Expand All @@ -864,7 +864,7 @@ struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
{
struct hci_conn *acl;

if (!test_bit(HCI_BREDR_ENABLED, &hdev->dev_flags)) {
if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) {
if (lmp_bredr_capable(hdev))
return ERR_PTR(-ECONNREFUSED);

Expand Down Expand Up @@ -942,7 +942,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
* Connections is used and the link is encrypted with AES-CCM
* using a P-256 authenticated combination key.
*/
if (test_bit(HCI_SC_ONLY, &conn->hdev->flags)) {
if (hci_dev_test_flag(conn->hdev, HCI_SC_ONLY)) {
if (!hci_conn_sc_enabled(conn) ||
!test_bit(HCI_CONN_AES_CCM, &conn->flags) ||
conn->key_type != HCI_LK_AUTH_COMBINATION_P256)
Expand Down
Loading

0 comments on commit 5f1764d

Please sign in to comment.