mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
This commit is contained in:
commit
992066c8d3
|
@ -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>;
|
||||
};
|
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
u32 val;
|
||||
|
||||
dt_node = of_find_node_by_name(NULL, name);
|
||||
if (!dt_node)
|
||||
return -ENODEV;
|
||||
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, property,
|
||||
cal_data + BT_CAL_HDR_LEN,
|
||||
BT_CAL_DATA_SIZE);
|
||||
if (ret)
|
||||
return ret;
|
||||
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;
|
||||
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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
struct link_key *key;
|
||||
|
||||
list_for_each_safe(p, n, &hdev->link_keys) {
|
||||
struct link_key *key;
|
||||
|
||||
key = list_entry(p, struct link_key, list);
|
||||
|
||||
list_del(p);
|
||||
kfree(key);
|
||||
list_for_each_entry_rcu(key, &hdev->link_keys, list) {
|
||||
list_del_rcu(&key->list);
|
||||
kfree_rcu(key, rcu);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -510,11 +510,9 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (ndev) {
|
||||
ret = register_netdevice(ndev);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
ret = register_netdevice(ndev);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
list_add_tail_rcu(&sdata->list, &local->interfaces);
|
||||
|
|
Loading…
Reference in New Issue