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
  • Loading branch information
linvjw committed Dec 1, 2014
2 parents 18ca438 + f6af675 commit 992066c
Show file tree
Hide file tree
Showing 13 changed files with 143 additions and 61 deletions.
29 changes: 29 additions & 0 deletions Documentation/devicetree/bindings/btmrvl.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
btmrvl
------

Required properties:

- compatible : must be "btmrvl,cfgdata"

Optional properties:

- btmrvl,cal-data : Calibration data downloaded to the device during
initialization. This is an array of 28 values(u8).

- btmrvl,gpio-gap : gpio and gap (in msecs) combination to be
configured.

Example:

GPIO pin 13 is configured as a wakeup source and GAP is set to 100 msecs
in below example.

btmrvl {
compatible = "btmrvl,cfgdata";

btmrvl,cal-data = /bits/ 8 <
0x37 0x01 0x1c 0x00 0xff 0xff 0xff 0xff 0x01 0x7f 0x04 0x02
0x00 0x00 0xba 0xce 0xc0 0xc6 0x2d 0x00 0x00 0x00 0x00 0x00
0x00 0x00 0xf0 0x00>;
btmrvl,gpio-gap = <0x0d64>;
};
2 changes: 2 additions & 0 deletions drivers/bluetooth/ath3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x13d3, 0x3408) },
{ USB_DEVICE(0x13d3, 0x3432) },

/* Atheros AR5BBU12 with sflash firmware */
Expand Down Expand Up @@ -158,6 +159,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU22 with sflash firmware */
Expand Down
51 changes: 30 additions & 21 deletions drivers/bluetooth/btmrvl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ void btmrvl_interrupt(struct btmrvl_private *priv)

priv->adapter->int_count++;

if (priv->adapter->hs_state == HS_ACTIVATED) {
BT_DBG("BT: HS DEACTIVATED in ISR!\n");
priv->adapter->hs_state = HS_DEACTIVATED;
}

wake_up_interruptible(&priv->main_thread.wait_q);
}
EXPORT_SYMBOL_GPL(btmrvl_interrupt);
Expand Down Expand Up @@ -323,6 +328,7 @@ int btmrvl_prepare_command(struct btmrvl_private *priv)
} else {
ret = priv->hw_wakeup_firmware(priv);
priv->adapter->hs_state = HS_DEACTIVATED;
BT_DBG("BT: HS DEACTIVATED due to host activity!\n");
}
}

Expand Down Expand Up @@ -492,29 +498,31 @@ static int btmrvl_download_cal_data(struct btmrvl_private *priv,
return 0;
}

static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
static int btmrvl_check_device_tree(struct btmrvl_private *priv)
{
struct device_node *dt_node;
u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
const char name[] = "btmrvl_caldata";
const char property[] = "btmrvl,caldata";
int ret;

dt_node = of_find_node_by_name(NULL, name);
if (!dt_node)
return -ENODEV;

ret = of_property_read_u8_array(dt_node, property,
cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE);
if (ret)
return ret;

BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
if (ret) {
BT_ERR("Fail to download calibrate data");
return ret;
u32 val;

for_each_compatible_node(dt_node, NULL, "btmrvl,cfgdata") {
ret = of_property_read_u32(dt_node, "btmrvl,gpio-gap", &val);
if (!ret)
priv->btmrvl_dev.gpio_gap = val;

ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data",
cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE);
if (ret)
return ret;

BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data,
BT_CAL_DATA_SIZE);
if (ret) {
BT_ERR("Fail to download calibrate data");
return ret;
}
}

return 0;
Expand All @@ -526,14 +534,15 @@ static int btmrvl_setup(struct hci_dev *hdev)

btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);

btmrvl_cal_data_dt(priv);
priv->btmrvl_dev.gpio_gap = 0xffff;

btmrvl_check_device_tree(priv);

btmrvl_pscan_window_reporting(priv, 0x01);

priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv);

priv->btmrvl_dev.gpio_gap = 0xffff;
btmrvl_send_hscfg_cmd(priv);

return 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU12 with sflash firmware */
Expand Down
1 change: 1 addition & 0 deletions include/net/bluetooth/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ struct smp_irk {

struct link_key {
struct list_head list;
struct rcu_head rcu;
bdaddr_t bdaddr;
u8 type;
u8 val[HCI_LINK_KEY_SIZE];
Expand Down
39 changes: 20 additions & 19 deletions net/bluetooth/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,15 +274,13 @@ static const struct file_operations inquiry_cache_fops = {
static int link_keys_show(struct seq_file *f, void *ptr)
{
struct hci_dev *hdev = f->private;
struct list_head *p, *n;
struct link_key *key;

hci_dev_lock(hdev);
list_for_each_safe(p, n, &hdev->link_keys) {
struct link_key *key = list_entry(p, struct link_key, list);
rcu_read_lock();
list_for_each_entry_rcu(key, &hdev->link_keys, list)
seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
HCI_LINK_KEY_SIZE, key->val, key->pin_len);
}
hci_dev_unlock(hdev);
rcu_read_unlock();

return 0;
}
Expand Down Expand Up @@ -1128,6 +1126,7 @@ struct sk_buff *__hci_cmd_sync_ev(struct hci_dev *hdev, u16 opcode, u32 plen,
err = hci_req_run(&req, hci_req_sync_complete);
if (err < 0) {
remove_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_RUNNING);
return ERR_PTR(err);
}

Expand Down Expand Up @@ -1196,6 +1195,7 @@ static int __hci_req_sync(struct hci_dev *hdev,
hdev->req_status = 0;

remove_wait_queue(&hdev->req_wait_q, &wait);
set_current_state(TASK_RUNNING);

/* ENODATA means the HCI request command queue is empty.
* This can happen when a request with conditionals doesn't
Expand Down Expand Up @@ -3099,15 +3099,11 @@ void hci_uuids_clear(struct hci_dev *hdev)

void hci_link_keys_clear(struct hci_dev *hdev)
{
struct list_head *p, *n;

list_for_each_safe(p, n, &hdev->link_keys) {
struct link_key *key;

key = list_entry(p, struct link_key, list);
struct link_key *key;

list_del(p);
kfree(key);
list_for_each_entry_rcu(key, &hdev->link_keys, list) {
list_del_rcu(&key->list);
kfree_rcu(key, rcu);
}
}

Expand Down Expand Up @@ -3135,9 +3131,14 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
{
struct link_key *k;

list_for_each_entry(k, &hdev->link_keys, list)
if (bacmp(bdaddr, &k->bdaddr) == 0)
rcu_read_lock();
list_for_each_entry_rcu(k, &hdev->link_keys, list) {
if (bacmp(bdaddr, &k->bdaddr) == 0) {
rcu_read_unlock();
return k;
}
}
rcu_read_unlock();

return NULL;
}
Expand Down Expand Up @@ -3288,7 +3289,7 @@ struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
key = kzalloc(sizeof(*key), GFP_KERNEL);
if (!key)
return NULL;
list_add(&key->list, &hdev->link_keys);
list_add_rcu(&key->list, &hdev->link_keys);
}

BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
Expand Down Expand Up @@ -3381,8 +3382,8 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)

BT_DBG("%s removing %pMR", hdev->name, bdaddr);

list_del(&key->list);
kfree(key);
list_del_rcu(&key->list);
kfree_rcu(key, rcu);

return 0;
}
Expand Down
51 changes: 42 additions & 9 deletions net/bluetooth/hci_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -3191,6 +3191,38 @@ static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
hci_dev_unlock(hdev);
}

static void conn_set_key(struct hci_conn *conn, u8 key_type, u8 pin_len)
{
if (key_type == HCI_LK_CHANGED_COMBINATION)
return;

conn->pin_length = pin_len;
conn->key_type = key_type;

switch (key_type) {
case HCI_LK_LOCAL_UNIT:
case HCI_LK_REMOTE_UNIT:
case HCI_LK_DEBUG_COMBINATION:
return;
case HCI_LK_COMBINATION:
if (pin_len == 16)
conn->pending_sec_level = BT_SECURITY_HIGH;
else
conn->pending_sec_level = BT_SECURITY_MEDIUM;
break;
case HCI_LK_UNAUTH_COMBINATION_P192:
case HCI_LK_UNAUTH_COMBINATION_P256:
conn->pending_sec_level = BT_SECURITY_MEDIUM;
break;
case HCI_LK_AUTH_COMBINATION_P192:
conn->pending_sec_level = BT_SECURITY_HIGH;
break;
case HCI_LK_AUTH_COMBINATION_P256:
conn->pending_sec_level = BT_SECURITY_FIPS;
break;
}
}

static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_link_key_req *ev = (void *) skb->data;
Expand Down Expand Up @@ -3232,8 +3264,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
goto not_found;
}

conn->key_type = key->type;
conn->pin_length = key->pin_len;
conn_set_key(conn, key->type, key->pin_len);
}

bacpy(&cp.bdaddr, &ev->bdaddr);
Expand Down Expand Up @@ -3266,12 +3297,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (conn) {
hci_conn_hold(conn);
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
pin_len = conn->pin_length;

if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
conn->key_type = ev->key_type;

hci_conn_drop(conn);
conn_set_key(conn, ev->key_type, conn->pin_length);
}

if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Expand All @@ -3282,6 +3309,12 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (!key)
goto unlock;

/* Update connection information since adding the key will have
* fixed up the type in the case of changed combination keys.
*/
if (ev->key_type == HCI_LK_CHANGED_COMBINATION)
conn_set_key(conn, key->type, key->pin_len);

mgmt_new_link_key(hdev, key, persistent);

/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
Expand All @@ -3291,8 +3324,8 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
*/
if (key->type == HCI_LK_DEBUG_COMBINATION &&
!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
list_del(&key->list);
kfree(key);
list_del_rcu(&key->list);
kfree_rcu(key, rcu);
} else if (conn) {
if (persistent)
clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
Expand Down
14 changes: 11 additions & 3 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,7 +840,10 @@ static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
if (!skb)
return;

if (lmp_no_flush_capable(conn->hcon->hdev))
/* Use NO_FLUSH if supported or we have an LE link (which does
* not support auto-flushing packets) */
if (lmp_no_flush_capable(conn->hcon->hdev) ||
conn->hcon->type == LE_LINK)
flags = ACL_START_NO_FLUSH;
else
flags = ACL_START;
Expand Down Expand Up @@ -874,8 +877,13 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
return;
}

if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
lmp_no_flush_capable(hcon->hdev))
/* Use NO_FLUSH for LE links (where this is the only option) or
* if the BR/EDR link supports it and flushing has not been
* explicitly requested (through FLAG_FLUSHABLE).
*/
if (hcon->type == LE_LINK ||
(!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
lmp_no_flush_capable(hcon->hdev)))
flags = ACL_START_NO_FLUSH;
else
flags = ACL_START;
Expand Down
2 changes: 1 addition & 1 deletion net/ieee802154/6lowpan_rtnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,

entry->ldev = dev;

/* Set the lowpan harware address to the wpan hardware address. */
/* Set the lowpan hardware address to the wpan hardware address. */
memcpy(dev->dev_addr, real_dev->dev_addr, IEEE802154_ADDR_LEN);

mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
Expand Down
2 changes: 1 addition & 1 deletion net/ieee802154/netlink.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Netlink inteface for IEEE 802.15.4 stack
* Netlink interface for IEEE 802.15.4 stack
*
* Copyright 2007, 2008 Siemens AG
*
Expand Down
2 changes: 1 addition & 1 deletion net/ieee802154/nl-mac.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Netlink inteface for IEEE 802.15.4 stack
* Netlink interface for IEEE 802.15.4 stack
*
* Copyright 2007, 2008 Siemens AG
*
Expand Down
2 changes: 1 addition & 1 deletion net/ieee802154/nl-phy.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Netlink inteface for IEEE 802.15.4 stack
* Netlink interface for IEEE 802.15.4 stack
*
* Copyright 2007, 2008 Siemens AG
*
Expand Down
Loading

0 comments on commit 992066c

Please sign in to comment.