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, 0x3375) },
|
||||||
{ USB_DEVICE(0x13d3, 0x3393) },
|
{ USB_DEVICE(0x13d3, 0x3393) },
|
||||||
{ USB_DEVICE(0x13d3, 0x3402) },
|
{ USB_DEVICE(0x13d3, 0x3402) },
|
||||||
|
{ USB_DEVICE(0x13d3, 0x3408) },
|
||||||
{ USB_DEVICE(0x13d3, 0x3432) },
|
{ USB_DEVICE(0x13d3, 0x3432) },
|
||||||
|
|
||||||
/* Atheros AR5BBU12 with sflash firmware */
|
/* 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, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3402), .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 },
|
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
|
||||||
|
|
||||||
/* Atheros AR5BBU22 with sflash firmware */
|
/* Atheros AR5BBU22 with sflash firmware */
|
||||||
|
|
|
@ -41,6 +41,11 @@ void btmrvl_interrupt(struct btmrvl_private *priv)
|
||||||
|
|
||||||
priv->adapter->int_count++;
|
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);
|
wake_up_interruptible(&priv->main_thread.wait_q);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(btmrvl_interrupt);
|
EXPORT_SYMBOL_GPL(btmrvl_interrupt);
|
||||||
|
@ -323,6 +328,7 @@ int btmrvl_prepare_command(struct btmrvl_private *priv)
|
||||||
} else {
|
} else {
|
||||||
ret = priv->hw_wakeup_firmware(priv);
|
ret = priv->hw_wakeup_firmware(priv);
|
||||||
priv->adapter->hs_state = HS_DEACTIVATED;
|
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;
|
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;
|
struct device_node *dt_node;
|
||||||
u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
|
u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
|
||||||
const char name[] = "btmrvl_caldata";
|
|
||||||
const char property[] = "btmrvl,caldata";
|
|
||||||
int ret;
|
int ret;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
dt_node = of_find_node_by_name(NULL, name);
|
for_each_compatible_node(dt_node, NULL, "btmrvl,cfgdata") {
|
||||||
if (!dt_node)
|
ret = of_property_read_u32(dt_node, "btmrvl,gpio-gap", &val);
|
||||||
return -ENODEV;
|
if (!ret)
|
||||||
|
priv->btmrvl_dev.gpio_gap = val;
|
||||||
|
|
||||||
ret = of_property_read_u8_array(dt_node, property,
|
ret = of_property_read_u8_array(dt_node, "btmrvl,cal-data",
|
||||||
cal_data + BT_CAL_HDR_LEN,
|
cal_data + BT_CAL_HDR_LEN,
|
||||||
BT_CAL_DATA_SIZE);
|
BT_CAL_DATA_SIZE);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
BT_DBG("Use cal data from device tree");
|
BT_DBG("Use cal data from device tree");
|
||||||
ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
|
ret = btmrvl_download_cal_data(priv, cal_data,
|
||||||
if (ret) {
|
BT_CAL_DATA_SIZE);
|
||||||
BT_ERR("Fail to download calibrate data");
|
if (ret) {
|
||||||
return ret;
|
BT_ERR("Fail to download calibrate data");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -526,14 +534,15 @@ static int btmrvl_setup(struct hci_dev *hdev)
|
||||||
|
|
||||||
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
|
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);
|
btmrvl_pscan_window_reporting(priv, 0x01);
|
||||||
|
|
||||||
priv->btmrvl_dev.psmode = 1;
|
priv->btmrvl_dev.psmode = 1;
|
||||||
btmrvl_enable_ps(priv);
|
btmrvl_enable_ps(priv);
|
||||||
|
|
||||||
priv->btmrvl_dev.gpio_gap = 0xffff;
|
|
||||||
btmrvl_send_hscfg_cmd(priv);
|
btmrvl_send_hscfg_cmd(priv);
|
||||||
|
|
||||||
return 0;
|
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, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||||
{ USB_DEVICE(0x13d3, 0x3402), .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 },
|
{ USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 },
|
||||||
|
|
||||||
/* Atheros AR5BBU12 with sflash firmware */
|
/* Atheros AR5BBU12 with sflash firmware */
|
||||||
|
|
|
@ -130,6 +130,7 @@ struct smp_irk {
|
||||||
|
|
||||||
struct link_key {
|
struct link_key {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
struct rcu_head rcu;
|
||||||
bdaddr_t bdaddr;
|
bdaddr_t bdaddr;
|
||||||
u8 type;
|
u8 type;
|
||||||
u8 val[HCI_LINK_KEY_SIZE];
|
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)
|
static int link_keys_show(struct seq_file *f, void *ptr)
|
||||||
{
|
{
|
||||||
struct hci_dev *hdev = f->private;
|
struct hci_dev *hdev = f->private;
|
||||||
struct list_head *p, *n;
|
struct link_key *key;
|
||||||
|
|
||||||
hci_dev_lock(hdev);
|
rcu_read_lock();
|
||||||
list_for_each_safe(p, n, &hdev->link_keys) {
|
list_for_each_entry_rcu(key, &hdev->link_keys, list)
|
||||||
struct link_key *key = list_entry(p, struct link_key, list);
|
|
||||||
seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
|
seq_printf(f, "%pMR %u %*phN %u\n", &key->bdaddr, key->type,
|
||||||
HCI_LINK_KEY_SIZE, key->val, key->pin_len);
|
HCI_LINK_KEY_SIZE, key->val, key->pin_len);
|
||||||
}
|
rcu_read_unlock();
|
||||||
hci_dev_unlock(hdev);
|
|
||||||
|
|
||||||
return 0;
|
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);
|
err = hci_req_run(&req, hci_req_sync_complete);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
remove_wait_queue(&hdev->req_wait_q, &wait);
|
remove_wait_queue(&hdev->req_wait_q, &wait);
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1196,6 +1195,7 @@ static int __hci_req_sync(struct hci_dev *hdev,
|
||||||
hdev->req_status = 0;
|
hdev->req_status = 0;
|
||||||
|
|
||||||
remove_wait_queue(&hdev->req_wait_q, &wait);
|
remove_wait_queue(&hdev->req_wait_q, &wait);
|
||||||
|
set_current_state(TASK_RUNNING);
|
||||||
|
|
||||||
/* ENODATA means the HCI request command queue is empty.
|
/* ENODATA means the HCI request command queue is empty.
|
||||||
* This can happen when a request with conditionals doesn't
|
* 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)
|
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) {
|
list_for_each_entry_rcu(key, &hdev->link_keys, list) {
|
||||||
struct link_key *key;
|
list_del_rcu(&key->list);
|
||||||
|
kfree_rcu(key, rcu);
|
||||||
key = list_entry(p, struct link_key, list);
|
|
||||||
|
|
||||||
list_del(p);
|
|
||||||
kfree(key);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3135,9 +3131,14 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
|
||||||
{
|
{
|
||||||
struct link_key *k;
|
struct link_key *k;
|
||||||
|
|
||||||
list_for_each_entry(k, &hdev->link_keys, list)
|
rcu_read_lock();
|
||||||
if (bacmp(bdaddr, &k->bdaddr) == 0)
|
list_for_each_entry_rcu(k, &hdev->link_keys, list) {
|
||||||
|
if (bacmp(bdaddr, &k->bdaddr) == 0) {
|
||||||
|
rcu_read_unlock();
|
||||||
return k;
|
return k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
return NULL;
|
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);
|
key = kzalloc(sizeof(*key), GFP_KERNEL);
|
||||||
if (!key)
|
if (!key)
|
||||||
return NULL;
|
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);
|
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);
|
BT_DBG("%s removing %pMR", hdev->name, bdaddr);
|
||||||
|
|
||||||
list_del(&key->list);
|
list_del_rcu(&key->list);
|
||||||
kfree(key);
|
kfree_rcu(key, rcu);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3191,6 +3191,38 @@ unlock:
|
||||||
hci_dev_unlock(hdev);
|
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)
|
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;
|
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;
|
goto not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->key_type = key->type;
|
conn_set_key(conn, key->type, key->pin_len);
|
||||||
conn->pin_length = key->pin_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bacpy(&cp.bdaddr, &ev->bdaddr);
|
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) {
|
if (conn) {
|
||||||
hci_conn_hold(conn);
|
hci_conn_hold(conn);
|
||||||
conn->disc_timeout = HCI_DISCONN_TIMEOUT;
|
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);
|
hci_conn_drop(conn);
|
||||||
|
conn_set_key(conn, ev->key_type, conn->pin_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_bit(HCI_MGMT, &hdev->dev_flags))
|
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)
|
if (!key)
|
||||||
goto unlock;
|
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);
|
mgmt_new_link_key(hdev, key, persistent);
|
||||||
|
|
||||||
/* Keep debug keys around only if the HCI_KEEP_DEBUG_KEYS flag
|
/* 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 &&
|
if (key->type == HCI_LK_DEBUG_COMBINATION &&
|
||||||
!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
|
!test_bit(HCI_KEEP_DEBUG_KEYS, &hdev->dev_flags)) {
|
||||||
list_del(&key->list);
|
list_del_rcu(&key->list);
|
||||||
kfree(key);
|
kfree_rcu(key, rcu);
|
||||||
} else if (conn) {
|
} else if (conn) {
|
||||||
if (persistent)
|
if (persistent)
|
||||||
clear_bit(HCI_CONN_FLUSH_KEY, &conn->flags);
|
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)
|
if (!skb)
|
||||||
return;
|
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;
|
flags = ACL_START_NO_FLUSH;
|
||||||
else
|
else
|
||||||
flags = ACL_START;
|
flags = ACL_START;
|
||||||
|
@ -874,8 +877,13 @@ static void l2cap_do_send(struct l2cap_chan *chan, struct sk_buff *skb)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_bit(FLAG_FLUSHABLE, &chan->flags) &&
|
/* Use NO_FLUSH for LE links (where this is the only option) or
|
||||||
lmp_no_flush_capable(hcon->hdev))
|
* 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;
|
flags = ACL_START_NO_FLUSH;
|
||||||
else
|
else
|
||||||
flags = ACL_START;
|
flags = ACL_START;
|
||||||
|
|
|
@ -597,7 +597,7 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
|
||||||
|
|
||||||
entry->ldev = 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);
|
memcpy(dev->dev_addr, real_dev->dev_addr, IEEE802154_ADDR_LEN);
|
||||||
|
|
||||||
mutex_lock(&lowpan_dev_info(dev)->dev_list_mtx);
|
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
|
* 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
|
* 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
|
* Copyright 2007, 2008 Siemens AG
|
||||||
*
|
*
|
||||||
|
|
|
@ -510,11 +510,9 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (ndev) {
|
ret = register_netdevice(ndev);
|
||||||
ret = register_netdevice(ndev);
|
if (ret < 0)
|
||||||
if (ret < 0)
|
goto err;
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex_lock(&local->iflist_mtx);
|
mutex_lock(&local->iflist_mtx);
|
||||||
list_add_tail_rcu(&sdata->list, &local->interfaces);
|
list_add_tail_rcu(&sdata->list, &local->interfaces);
|
||||||
|
|
Loading…
Reference in New Issue