Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
53730107
Commit
53730107
authored
Jul 03, 2014
by
Marcel Holtmann
Browse files
Options
Browse Files
Download
Plain Diff
Merge
git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth
parents
15be8e89
48439d50
Changes
20
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
254 additions
and
106 deletions
+254
-106
drivers/bluetooth/ath3k.c
drivers/bluetooth/ath3k.c
+0
-2
drivers/bluetooth/btusb.c
drivers/bluetooth/btusb.c
+0
-1
drivers/bluetooth/hci_h5.c
drivers/bluetooth/hci_h5.c
+1
-0
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/Kconfig
+1
-1
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/main.c
+1
-0
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43/xmit.c
+7
-3
drivers/net/wireless/mwifiex/pcie.c
drivers/net/wireless/mwifiex/pcie.c
+2
-2
drivers/net/wireless/mwifiex/util.h
drivers/net/wireless/mwifiex/util.h
+33
-10
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
+6
-1
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2800usb.c
+36
-3
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00.h
+1
-0
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00dev.c
+21
-3
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00mac.c
+2
-0
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt2x00usb.h
+1
-0
net/bluetooth/hci_conn.c
net/bluetooth/hci_conn.c
+12
-7
net/bluetooth/hci_event.c
net/bluetooth/hci_event.c
+14
-3
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_core.c
+7
-1
net/bluetooth/l2cap_sock.c
net/bluetooth/l2cap_sock.c
+0
-5
net/bluetooth/mgmt.c
net/bluetooth/mgmt.c
+56
-48
net/bluetooth/smp.c
net/bluetooth/smp.c
+53
-16
No files found.
drivers/bluetooth/ath3k.c
View file @
53730107
...
...
@@ -90,7 +90,6 @@ static const struct usb_device_id ath3k_table[] = {
{
USB_DEVICE
(
0x0b05
,
0x17d0
)
},
{
USB_DEVICE
(
0x0CF3
,
0x0036
)
},
{
USB_DEVICE
(
0x0CF3
,
0x3004
)
},
{
USB_DEVICE
(
0x0CF3
,
0x3005
)
},
{
USB_DEVICE
(
0x0CF3
,
0x3008
)
},
{
USB_DEVICE
(
0x0CF3
,
0x311D
)
},
{
USB_DEVICE
(
0x0CF3
,
0x311E
)
},
...
...
@@ -140,7 +139,6 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{
USB_DEVICE
(
0x0b05
,
0x17d0
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0CF3
,
0x0036
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3004
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3005
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3008
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x311D
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x311E
),
.
driver_info
=
BTUSB_ATH3012
},
...
...
drivers/bluetooth/btusb.c
View file @
53730107
...
...
@@ -162,7 +162,6 @@ static const struct usb_device_id blacklist_table[] = {
{
USB_DEVICE
(
0x0b05
,
0x17d0
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x0036
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3004
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3005
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x3008
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x311d
),
.
driver_info
=
BTUSB_ATH3012
},
{
USB_DEVICE
(
0x0cf3
,
0x311e
),
.
driver_info
=
BTUSB_ATH3012
},
...
...
drivers/bluetooth/hci_h5.c
View file @
53730107
...
...
@@ -406,6 +406,7 @@ static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c)
H5_HDR_PKT_TYPE
(
hdr
)
!=
HCI_3WIRE_LINK_PKT
)
{
BT_ERR
(
"Non-link packet received in non-active state"
);
h5_reset_rx
(
h5
);
return
0
;
}
h5
->
rx_func
=
h5_rx_payload
;
...
...
drivers/net/wireless/b43/Kconfig
View file @
53730107
...
...
@@ -36,7 +36,7 @@ config B43_SSB
choice
prompt "Supported bus types"
depends on B43
default B43_BCMA_AND_SSB
default B43_B
USES_B
CMA_AND_SSB
config B43_BUSES_BCMA_AND_SSB
bool "BCMA and SSB"
...
...
drivers/net/wireless/b43/main.c
View file @
53730107
...
...
@@ -5241,6 +5241,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
/* We don't support 5 GHz on some PHYs yet */
switch
(
dev
->
phy
.
type
)
{
case
B43_PHYTYPE_A
:
case
B43_PHYTYPE_G
:
case
B43_PHYTYPE_N
:
case
B43_PHYTYPE_LP
:
case
B43_PHYTYPE_HT
:
...
...
drivers/net/wireless/b43/xmit.c
View file @
53730107
...
...
@@ -811,8 +811,12 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
break
;
case
B43_PHYTYPE_G
:
status
.
band
=
IEEE80211_BAND_2GHZ
;
/* chanid is the radio channel cookie value as used
* to tune the radio. */
/* Somewhere between 478.104 and 508.1084 firmware for G-PHY
* has been modified to be compatible with N-PHY and others.
*/
if
(
dev
->
fw
.
rev
>=
508
)
status
.
freq
=
ieee80211_channel_to_frequency
(
chanid
,
status
.
band
);
else
status
.
freq
=
chanid
+
2400
;
break
;
case
B43_PHYTYPE_N
:
...
...
drivers/net/wireless/mwifiex/pcie.c
View file @
53730107
...
...
@@ -57,7 +57,7 @@ mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
return
-
1
;
}
mapping
.
len
=
size
;
m
emcpy
(
skb
->
cb
,
&
mapping
,
sizeof
(
mapping
)
);
m
wifiex_store_mapping
(
skb
,
&
mapping
);
return
0
;
}
...
...
@@ -67,7 +67,7 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter,
struct
pcie_service_card
*
card
=
adapter
->
card
;
struct
mwifiex_dma_mapping
mapping
;
MWIFIEX_SKB_PACB
(
skb
,
&
mapping
);
mwifiex_get_mapping
(
skb
,
&
mapping
);
pci_unmap_single
(
card
->
dev
,
mapping
.
addr
,
mapping
.
len
,
flags
);
}
...
...
drivers/net/wireless/mwifiex/util.h
View file @
53730107
...
...
@@ -20,32 +20,55 @@
#ifndef _MWIFIEX_UTIL_H_
#define _MWIFIEX_UTIL_H_
struct
mwifiex_dma_mapping
{
dma_addr_t
addr
;
size_t
len
;
};
struct
mwifiex_cb
{
struct
mwifiex_dma_mapping
dma_mapping
;
union
{
struct
mwifiex_rxinfo
rx_info
;
struct
mwifiex_txinfo
tx_info
;
};
};
static
inline
struct
mwifiex_rxinfo
*
MWIFIEX_SKB_RXCB
(
struct
sk_buff
*
skb
)
{
return
(
struct
mwifiex_rxinfo
*
)(
skb
->
cb
+
sizeof
(
dma_addr_t
));
struct
mwifiex_cb
*
cb
=
(
struct
mwifiex_cb
*
)
skb
->
cb
;
BUILD_BUG_ON
(
sizeof
(
struct
mwifiex_cb
)
>
sizeof
(
skb
->
cb
));
return
&
cb
->
rx_info
;
}
static
inline
struct
mwifiex_txinfo
*
MWIFIEX_SKB_TXCB
(
struct
sk_buff
*
skb
)
{
return
(
struct
mwifiex_txinfo
*
)(
skb
->
cb
+
sizeof
(
dma_addr_t
));
struct
mwifiex_cb
*
cb
=
(
struct
mwifiex_cb
*
)
skb
->
cb
;
return
&
cb
->
tx_info
;
}
struct
mwifiex_dma_mapping
{
dma_addr_t
addr
;
size_t
len
;
};
static
inline
void
mwifiex_store_mapping
(
struct
sk_buff
*
skb
,
struct
mwifiex_dma_mapping
*
mapping
)
{
struct
mwifiex_cb
*
cb
=
(
struct
mwifiex_cb
*
)
skb
->
cb
;
memcpy
(
&
cb
->
dma_mapping
,
mapping
,
sizeof
(
*
mapping
));
}
static
inline
void
MWIFIEX_SKB_PACB
(
struct
sk_buff
*
skb
,
static
inline
void
mwifiex_get_mapping
(
struct
sk_buff
*
skb
,
struct
mwifiex_dma_mapping
*
mapping
)
{
memcpy
(
mapping
,
skb
->
cb
,
sizeof
(
*
mapping
));
struct
mwifiex_cb
*
cb
=
(
struct
mwifiex_cb
*
)
skb
->
cb
;
memcpy
(
mapping
,
&
cb
->
dma_mapping
,
sizeof
(
*
mapping
));
}
static
inline
dma_addr_t
MWIFIEX_SKB_DMA_ADDR
(
struct
sk_buff
*
skb
)
{
struct
mwifiex_dma_mapping
mapping
;
MWIFIEX_SKB_PACB
(
skb
,
&
mapping
);
mwifiex_get_mapping
(
skb
,
&
mapping
);
return
mapping
.
addr
;
}
...
...
drivers/net/wireless/rt2x00/rt2500pci.c
View file @
53730107
...
...
@@ -1681,8 +1681,13 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
/*
* Detect if this device has an hardware controlled radio.
*/
if
(
rt2x00_get_field16
(
eeprom
,
EEPROM_ANTENNA_HARDWARE_RADIO
))
if
(
rt2x00_get_field16
(
eeprom
,
EEPROM_ANTENNA_HARDWARE_RADIO
))
{
__set_bit
(
CAPABILITY_HW_BUTTON
,
&
rt2x00dev
->
cap_flags
);
/*
* On this device RFKILL initialized during probe does not work.
*/
__set_bit
(
REQUIRE_DELAYED_RFKILL
,
&
rt2x00dev
->
cap_flags
);
}
/*
* Check if the BBP tuning should be enabled.
...
...
drivers/net/wireless/rt2x00/rt2800usb.c
View file @
53730107
...
...
@@ -229,6 +229,27 @@ static enum hrtimer_restart rt2800usb_tx_sta_fifo_timeout(struct hrtimer *timer)
/*
* Firmware functions
*/
static
int
rt2800usb_autorun_detect
(
struct
rt2x00_dev
*
rt2x00dev
)
{
__le32
reg
;
u32
fw_mode
;
/* cannot use rt2x00usb_register_read here as it uses different
* mode (MULTI_READ vs. DEVICE_MODE) and does not pass the
* magic value USB_MODE_AUTORUN (0x11) to the device, thus the
* returned value would be invalid.
*/
rt2x00usb_vendor_request
(
rt2x00dev
,
USB_DEVICE_MODE
,
USB_VENDOR_REQUEST_IN
,
0
,
USB_MODE_AUTORUN
,
&
reg
,
sizeof
(
reg
),
REGISTER_TIMEOUT_FIRMWARE
);
fw_mode
=
le32_to_cpu
(
reg
);
if
((
fw_mode
&
0x00000003
)
==
2
)
return
1
;
return
0
;
}
static
char
*
rt2800usb_get_firmware_name
(
struct
rt2x00_dev
*
rt2x00dev
)
{
return
FIRMWARE_RT2870
;
...
...
@@ -257,8 +278,13 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
/*
* Write firmware to device.
*/
if
(
rt2800usb_autorun_detect
(
rt2x00dev
))
{
rt2x00_info
(
rt2x00dev
,
"Firmware loading not required - NIC in AutoRun mode
\n
"
);
}
else
{
rt2x00usb_register_multiwrite
(
rt2x00dev
,
FIRMWARE_IMAGE_BASE
,
data
+
offset
,
length
);
}
rt2x00usb_register_write
(
rt2x00dev
,
H2M_MAILBOX_CID
,
~
0
);
rt2x00usb_register_write
(
rt2x00dev
,
H2M_MAILBOX_STATUS
,
~
0
);
...
...
@@ -735,11 +761,18 @@ static void rt2800usb_fill_rxdone(struct queue_entry *entry,
/*
* Device probe functions.
*/
static
int
rt2800usb_efuse_detect
(
struct
rt2x00_dev
*
rt2x00dev
)
{
if
(
rt2800usb_autorun_detect
(
rt2x00dev
))
return
1
;
return
rt2800_efuse_detect
(
rt2x00dev
);
}
static
int
rt2800usb_read_eeprom
(
struct
rt2x00_dev
*
rt2x00dev
)
{
int
retval
;
if
(
rt2800_efuse_detect
(
rt2x00dev
))
if
(
rt2800
usb
_efuse_detect
(
rt2x00dev
))
retval
=
rt2800_read_eeprom_efuse
(
rt2x00dev
);
else
retval
=
rt2x00usb_eeprom_read
(
rt2x00dev
,
rt2x00dev
->
eeprom
,
...
...
drivers/net/wireless/rt2x00/rt2x00.h
View file @
53730107
...
...
@@ -693,6 +693,7 @@ enum rt2x00_capability_flags {
REQUIRE_SW_SEQNO
,
REQUIRE_HT_TX_DESC
,
REQUIRE_PS_AUTOWAKE
,
REQUIRE_DELAYED_RFKILL
,
/*
* Capabilities
...
...
drivers/net/wireless/rt2x00/rt2x00dev.c
View file @
53730107
...
...
@@ -1129,8 +1129,9 @@ static void rt2x00lib_uninitialize(struct rt2x00_dev *rt2x00dev)
return
;
/*
*
Unregister extra components
.
*
Stop rfkill polling
.
*/
if
(
test_bit
(
REQUIRE_DELAYED_RFKILL
,
&
rt2x00dev
->
cap_flags
))
rt2x00rfkill_unregister
(
rt2x00dev
);
/*
...
...
@@ -1169,6 +1170,12 @@ static int rt2x00lib_initialize(struct rt2x00_dev *rt2x00dev)
set_bit
(
DEVICE_STATE_INITIALIZED
,
&
rt2x00dev
->
flags
);
/*
* Start rfkill polling.
*/
if
(
test_bit
(
REQUIRE_DELAYED_RFKILL
,
&
rt2x00dev
->
cap_flags
))
rt2x00rfkill_register
(
rt2x00dev
);
return
0
;
}
...
...
@@ -1378,6 +1385,11 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
rt2x00link_register
(
rt2x00dev
);
rt2x00leds_register
(
rt2x00dev
);
rt2x00debug_register
(
rt2x00dev
);
/*
* Start rfkill polling.
*/
if
(
!
test_bit
(
REQUIRE_DELAYED_RFKILL
,
&
rt2x00dev
->
cap_flags
))
rt2x00rfkill_register
(
rt2x00dev
);
return
0
;
...
...
@@ -1393,6 +1405,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
{
clear_bit
(
DEVICE_STATE_PRESENT
,
&
rt2x00dev
->
flags
);
/*
* Stop rfkill polling.
*/
if
(
!
test_bit
(
REQUIRE_DELAYED_RFKILL
,
&
rt2x00dev
->
cap_flags
))
rt2x00rfkill_unregister
(
rt2x00dev
);
/*
* Disable radio.
*/
...
...
drivers/net/wireless/rt2x00/rt2x00mac.c
View file @
53730107
...
...
@@ -487,6 +487,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
crypto
.
cipher
=
rt2x00crypto_key_to_cipher
(
key
);
if
(
crypto
.
cipher
==
CIPHER_NONE
)
return
-
EOPNOTSUPP
;
if
(
crypto
.
cipher
==
CIPHER_TKIP
&&
rt2x00_is_usb
(
rt2x00dev
))
return
-
EOPNOTSUPP
;
crypto
.
cmd
=
cmd
;
...
...
drivers/net/wireless/rt2x00/rt2x00usb.h
View file @
53730107
...
...
@@ -93,6 +93,7 @@ enum rt2x00usb_mode_offset {
USB_MODE_SLEEP
=
7
,
/* RT73USB */
USB_MODE_FIRMWARE
=
8
,
/* RT73USB */
USB_MODE_WAKEUP
=
9
,
/* RT73USB */
USB_MODE_AUTORUN
=
17
,
/* RT2800USB */
};
/**
...
...
net/bluetooth/hci_conn.c
View file @
53730107
...
...
@@ -289,10 +289,20 @@ static void hci_conn_timeout(struct work_struct *work)
{
struct
hci_conn
*
conn
=
container_of
(
work
,
struct
hci_conn
,
disc_work
.
work
);
int
refcnt
=
atomic_read
(
&
conn
->
refcnt
);
BT_DBG
(
"hcon %p state %s"
,
conn
,
state_to_string
(
conn
->
state
));
if
(
atomic_read
(
&
conn
->
refcnt
))
WARN_ON
(
refcnt
<
0
);
/* FIXME: It was observed that in pairing failed scenario, refcnt
* drops below 0. Probably this is because l2cap_conn_del calls
* l2cap_chan_del for each channel, and inside l2cap_chan_del conn is
* dropped. After that loop hci_chan_del is called which also drops
* conn. For now make sure that ACL is alive if refcnt is higher then 0,
* otherwise drop it.
*/
if
(
refcnt
>
0
)
return
;
switch
(
conn
->
state
)
{
...
...
@@ -610,11 +620,6 @@ static void hci_req_add_le_create_conn(struct hci_request *req,
if
(
hci_update_random_address
(
req
,
false
,
&
own_addr_type
))
return
;
/* Save the address type used for this connnection attempt so we able
* to retrieve this information if we need it.
*/
conn
->
src_type
=
own_addr_type
;
cp
.
scan_interval
=
cpu_to_le16
(
hdev
->
le_scan_interval
);
cp
.
scan_window
=
cpu_to_le16
(
hdev
->
le_scan_window
);
bacpy
(
&
cp
.
peer_addr
,
&
conn
->
dst
);
...
...
@@ -894,7 +899,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
/* If we're already encrypted set the REAUTH_PEND flag,
* otherwise set the ENCRYPT_PEND.
*/
if
(
conn
->
key_type
!=
0xff
)
if
(
conn
->
link_mode
&
HCI_LM_ENCRYPT
)
set_bit
(
HCI_CONN_REAUTH_PEND
,
&
conn
->
flags
);
else
set_bit
(
HCI_CONN_ENCRYPT_PEND
,
&
conn
->
flags
);
...
...
net/bluetooth/hci_event.c
View file @
53730107
...
...
@@ -48,6 +48,10 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
smp_mb__after_atomic
();
/* wake_up_bit advises about this barrier */
wake_up_bit
(
&
hdev
->
flags
,
HCI_INQUIRY
);
hci_dev_lock
(
hdev
);
hci_discovery_set_state
(
hdev
,
DISCOVERY_STOPPED
);
hci_dev_unlock
(
hdev
);
hci_conn_check_pending
(
hdev
);
}
...
...
@@ -3537,7 +3541,11 @@ static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
cp
.
authentication
=
conn
->
auth_type
;
/* Request MITM protection if our IO caps allow it
* except for the no-bonding case
* except for the no-bonding case.
* conn->auth_type is not updated here since
* that might cause the user confirmation to be
* rejected in case the remote doesn't have the
* IO capabilities for MITM.
*/
if
(
conn
->
io_capability
!=
HCI_IO_NO_INPUT_OUTPUT
&&
cp
.
authentication
!=
HCI_AT_NO_BONDING
)
...
...
@@ -3628,8 +3636,11 @@ static void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If we're not the initiators request authorization to
* proceed from user space (mgmt_user_confirm with
* confirm_hint set to 1). */
if
(
!
test_bit
(
HCI_CONN_AUTH_PEND
,
&
conn
->
flags
))
{
* confirm_hint set to 1). The exception is if neither
* side had MITM in which case we do auto-accept.
*/
if
(
!
test_bit
(
HCI_CONN_AUTH_PEND
,
&
conn
->
flags
)
&&
(
loc_mitm
||
rem_mitm
))
{
BT_DBG
(
"Confirming auto-accept as acceptor"
);
confirm_hint
=
1
;
goto
confirm
;
...
...
net/bluetooth/l2cap_core.c
View file @
53730107
...
...
@@ -1663,7 +1663,13 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
kfree_skb
(
conn
->
rx_skb
);
skb_queue_purge
(
&
conn
->
pending_rx
);
flush_work
(
&
conn
->
pending_rx_work
);
/* We can not call flush_work(&conn->pending_rx_work) here since we
* might block if we are running on a worker from the same workqueue
* pending_rx_work is waiting on.
*/
if
(
work_pending
(
&
conn
->
pending_rx_work
))
cancel_work_sync
(
&
conn
->
pending_rx_work
);
l2cap_unregister_all_users
(
conn
);
...
...
net/bluetooth/l2cap_sock.c
View file @
53730107
...
...
@@ -787,11 +787,6 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
/*change security for LE channels */
if
(
chan
->
scid
==
L2CAP_CID_ATT
)
{
if
(
!
conn
->
hcon
->
out
)
{
err
=
-
EINVAL
;
break
;
}
if
(
smp_conn_security
(
conn
->
hcon
,
sec
.
level
))
break
;
sk
->
sk_state
=
BT_CONFIG
;
...
...
net/bluetooth/mgmt.c
View file @
53730107
...
...
@@ -1047,6 +1047,43 @@ static void clean_up_hci_complete(struct hci_dev *hdev, u8 status)
}
}
static
void
hci_stop_discovery
(
struct
hci_request
*
req
)
{
struct
hci_dev
*
hdev
=
req
->
hdev
;
struct
hci_cp_remote_name_req_cancel
cp
;
struct
inquiry_entry
*
e
;
switch
(
hdev
->
discovery
.
state
)
{
case
DISCOVERY_FINDING
:
if
(
test_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
{
hci_req_add
(
req
,
HCI_OP_INQUIRY_CANCEL
,
0
,
NULL
);
}
else
{
cancel_delayed_work
(
&
hdev
->
le_scan_disable
);
hci_req_add_le_scan_disable
(
req
);
}
break
;
case
DISCOVERY_RESOLVING
:
e
=
hci_inquiry_cache_lookup_resolve
(
hdev
,
BDADDR_ANY
,
NAME_PENDING
);
if
(
!
e
)
return
;
bacpy
(
&
cp
.
bdaddr
,
&
e
->
data
.
bdaddr
);
hci_req_add
(
req
,
HCI_OP_REMOTE_NAME_REQ_CANCEL
,
sizeof
(
cp
),
&
cp
);
break
;
default:
/* Passive scanning */
if
(
test_bit
(
HCI_LE_SCAN
,
&
hdev
->
dev_flags
))
hci_req_add_le_scan_disable
(
req
);
break
;
}
}
static
int
clean_up_hci_state
(
struct
hci_dev
*
hdev
)
{
struct
hci_request
req
;
...
...
@@ -1063,9 +1100,7 @@ static int clean_up_hci_state(struct hci_dev *hdev)
if
(
test_bit
(
HCI_ADVERTISING
,
&
hdev
->
dev_flags
))
disable_advertising
(
&
req
);
if
(
test_bit
(
HCI_LE_SCAN
,
&
hdev
->
dev_flags
))
{
hci_req_add_le_scan_disable
(
&
req
);
}
hci_stop_discovery
(
&
req
);
list_for_each_entry
(
conn
,
&
hdev
->
conn_hash
.
list
,
list
)
{
struct
hci_cp_disconnect
dc
;
...
...
@@ -2996,8 +3031,13 @@ static int user_pairing_resp(struct sock *sk, struct hci_dev *hdev,
}
if
(
addr
->
type
==
BDADDR_LE_PUBLIC
||
addr
->
type
==
BDADDR_LE_RANDOM
)
{
/* Continue with pairing via SMP */
/* Continue with pairing via SMP. The hdev lock must be
* released as SMP may try to recquire it for crypto
* purposes.
*/
hci_dev_unlock
(
hdev
);
err
=
smp_user_confirm_reply
(
conn
,
mgmt_op
,
passkey
);
hci_dev_lock
(
hdev
);
if
(
!
err
)
err
=
cmd_complete
(
sk
,
hdev
->
id
,
mgmt_op
,
...
...
@@ -3574,8 +3614,6 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
{
struct
mgmt_cp_stop_discovery
*
mgmt_cp
=
data
;
struct
pending_cmd
*
cmd
;
struct
hci_cp_remote_name_req_cancel
cp
;
struct
inquiry_entry
*
e
;
struct
hci_request
req
;
int
err
;
...
...
@@ -3605,52 +3643,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data,
hci_req_init
(
&
req
,
hdev
);
switch
(
hdev
->
discovery
.
state
)
{
case
DISCOVERY_FINDING
:
if
(
test_bit
(
HCI_INQUIRY
,
&
hdev
->
flags
))
{
hci_req_add
(
&
req
,
HCI_OP_INQUIRY_CANCEL
,
0
,
NULL
);
}
else
{
cancel_delayed_work
(
&
hdev
->
le_scan_disable
);
hci_req_add_le_scan_disable
(
&
req
);
}
hci_stop_discovery
(
&
req
);
break
;
case
DISCOVERY_RESOLVING
:
e
=
hci_inquiry_cache_lookup_resolve
(
hdev
,
BDADDR_ANY
,
NAME_PENDING
);
if
(
!
e
)
{
mgmt_pending_remove
(
cmd
);
err
=
cmd_complete
(
sk
,
hdev
->
id
,
MGMT_OP_STOP_DISCOVERY
,
0
,
&
mgmt_cp
->
type
,
sizeof
(
mgmt_cp
->
type
));
hci_discovery_set_state
(
hdev
,
DISCOVERY_STOPPED
);
err
=
hci_req_run
(
&
req
,
stop_discovery_complete
);
if
(
!
err
)
{
hci_discovery_set_state
(
hdev
,
DISCOVERY_STOPPING
);
goto
unlock
;
}
bacpy
(
&
cp
.
bdaddr
,
&
e
->
data
.
bdaddr
);
hci_req_add
(
&
req
,
HCI_OP_REMOTE_NAME_REQ_CANCEL
,
sizeof
(
cp
),
&
cp
);
break
;
default:
BT_DBG
(
"unknown discovery state %u"
,
hdev
->
discovery
.
state
);
mgmt_pending_remove
(
cmd
);
err
=
cmd_complete
(
sk
,
hdev
->
id
,
MGMT_OP_STOP_DISCOVERY
,
MGMT_STATUS_FAILED
,
&
mgmt_cp
->
type
,
sizeof
(
mgmt_cp
->
type
));
goto
unlock
;
}
err
=
hci_req_run
(
&
req
,
stop_discovery_complete
);
if
(
err
<
0
)
mgmt_pending_remove
(
cmd
);
else
hci_discovery_set_state
(
hdev
,
DISCOVERY_STOPPING
);
/* If no HCI commands were sent we're done */
if
(
err
==
-
ENODATA
)
{
err
=
cmd_complete
(
sk
,
hdev
->
id
,
MGMT_OP_STOP_DISCOVERY
,
0
,
&
mgmt_cp
->
type
,
sizeof
(
mgmt_cp
->
type
));
hci_discovery_set_state
(
hdev
,
DISCOVERY_STOPPED
);
}
unlock:
hci_dev_unlock
(
hdev
);
...
...
net/bluetooth/smp.c
View file @
53730107
...
...
@@ -385,6 +385,16 @@ static const u8 gen_method[5][5] = {
{
CFM_PASSKEY
,
CFM_PASSKEY
,
REQ_PASSKEY
,
JUST_WORKS
,
OVERLAP
},
};
static
u8
get_auth_method
(
struct
smp_chan
*
smp
,
u8
local_io
,
u8
remote_io
)
{
/* If either side has unknown io_caps, use JUST WORKS */
if
(
local_io
>
SMP_IO_KEYBOARD_DISPLAY
||
remote_io
>
SMP_IO_KEYBOARD_DISPLAY
)
return
JUST_WORKS
;
return
gen_method
[
remote_io
][
local_io
];
}
static
int
tk_request
(
struct
l2cap_conn
*
conn
,
u8
remote_oob
,
u8
auth
,
u8
local_io
,
u8
remote_io
)
{
...
...
@@ -401,14 +411,11 @@ static int tk_request(struct l2cap_conn *conn, u8 remote_oob, u8 auth,
BT_DBG
(
"tk_request: auth:%d lcl:%d rem:%d"
,
auth
,
local_io
,
remote_io
);
/* If neither side wants MITM, use JUST WORKS */
/* If either side has unknown io_caps, use JUST WORKS */
/* Otherwise, look up method from the table */
if
(
!
(
auth
&
SMP_AUTH_MITM
)
||
local_io
>
SMP_IO_KEYBOARD_DISPLAY
||
remote_io
>
SMP_IO_KEYBOARD_DISPLAY
)
if
(
!
(
auth
&
SMP_AUTH_MITM
))
method
=
JUST_WORKS
;
else
method
=
ge
n_method
[
remote_io
][
local_io
]
;
method
=
ge
t_auth_method
(
smp
,
local_io
,
remote_io
)
;
/* If not bonding, don't ask user to confirm a Zero TK */
if
(
!
(
auth
&
SMP_AUTH_BONDING
)
&&
method
==
JUST_CFM
)
...
...
@@ -544,7 +551,7 @@ static u8 smp_random(struct smp_chan *smp)
hci_le_start_enc
(
hcon
,
ediv
,
rand
,
stk
);
hcon
->
enc_key_size
=
smp
->
enc_key_size
;
}
else
{
u8
stk
[
16
];
u8
stk
[
16
]
,
auth
;
__le64
rand
=
0
;
__le16
ediv
=
0
;
...
...
@@ -556,8 +563,13 @@ static u8 smp_random(struct smp_chan *smp)
memset
(
stk
+
smp
->
enc_key_size
,
0
,
SMP_MAX_ENC_KEY_SIZE
-
smp
->
enc_key_size
);
if
(
hcon
->
pending_sec_level
==
BT_SECURITY_HIGH
)
auth
=
1
;
else
auth
=
0
;
hci_add_ltk
(
hcon
->
hdev
,
&
hcon
->
dst
,
hcon
->
dst_type
,
HCI_SMP_STK_SLAVE
,
0
,
stk
,
smp
->
enc_key_size
,
HCI_SMP_STK_SLAVE
,
auth
,
stk
,
smp
->
enc_key_size
,
ediv
,
rand
);
}
...
...
@@ -664,7 +676,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct
smp_cmd_pairing
rsp
,
*
req
=
(
void
*
)
skb
->
data
;
struct
smp_chan
*
smp
;
u8
key_size
,
auth
;
u8
key_size
,
auth
,
sec_level
;
int
ret
;
BT_DBG
(
"conn %p"
,
conn
);
...
...
@@ -690,7 +702,19 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
/* We didn't start the pairing, so match remote */
auth
=
req
->
auth_req
;
conn
->
hcon
->
pending_sec_level
=
authreq_to_seclevel
(
auth
);
sec_level
=
authreq_to_seclevel
(
auth
);
if
(
sec_level
>
conn
->
hcon
->
pending_sec_level
)
conn
->
hcon
->
pending_sec_level
=
sec_level
;
/* If we need MITM check that it can be acheived */
if
(
conn
->
hcon
->
pending_sec_level
>=
BT_SECURITY_HIGH
)
{
u8
method
;
method
=
get_auth_method
(
smp
,
conn
->
hcon
->
io_capability
,
req
->
io_capability
);
if
(
method
==
JUST_WORKS
||
method
==
JUST_CFM
)
return
SMP_AUTH_REQUIREMENTS
;
}
build_pairing_cmd
(
conn
,
req
,
&
rsp
,
auth
);
...
...
@@ -738,6 +762,16 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
if
(
check_enc_key_size
(
conn
,
key_size
))
return
SMP_ENC_KEY_SIZE
;
/* If we need MITM check that it can be acheived */
if
(
conn
->
hcon
->
pending_sec_level
>=
BT_SECURITY_HIGH
)
{
u8
method
;
method
=
get_auth_method
(
smp
,
req
->
io_capability
,
rsp
->
io_capability
);
if
(
method
==
JUST_WORKS
||
method
==
JUST_CFM
)
return
SMP_AUTH_REQUIREMENTS
;
}
get_random_bytes
(
smp
->
prnd
,
sizeof
(
smp
->
prnd
));
smp
->
prsp
[
0
]
=
SMP_CMD_PAIRING_RSP
;
...
...
@@ -833,6 +867,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
struct
smp_cmd_pairing
cp
;
struct
hci_conn
*
hcon
=
conn
->
hcon
;
struct
smp_chan
*
smp
;
u8
sec_level
;
BT_DBG
(
"conn %p"
,
conn
);
...
...
@@ -842,7 +877,9 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
if
(
!
(
conn
->
hcon
->
link_mode
&
HCI_LM_MASTER
))
return
SMP_CMD_NOTSUPP
;
hcon
->
pending_sec_level
=
authreq_to_seclevel
(
rp
->
auth_req
);
sec_level
=
authreq_to_seclevel
(
rp
->
auth_req
);
if
(
sec_level
>
hcon
->
pending_sec_level
)
hcon
->
pending_sec_level
=
sec_level
;
if
(
smp_ltk_encrypt
(
conn
,
hcon
->
pending_sec_level
))
return
0
;
...
...
@@ -896,9 +933,12 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
if
(
smp_sufficient_security
(
hcon
,
sec_level
))
return
1
;
if
(
sec_level
>
hcon
->
pending_sec_level
)
hcon
->
pending_sec_level
=
sec_level
;
if
(
hcon
->
link_mode
&
HCI_LM_MASTER
)
if
(
smp_ltk_encrypt
(
conn
,
sec_level
))
goto
done
;
if
(
smp_ltk_encrypt
(
conn
,
hcon
->
pending_
sec_level
))
return
0
;
if
(
test_and_set_bit
(
HCI_CONN_LE_SMP_PEND
,
&
hcon
->
flags
))
return
0
;
...
...
@@ -913,7 +953,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
* requires it.
*/
if
(
hcon
->
io_capability
!=
HCI_IO_NO_INPUT_OUTPUT
||
sec_level
>
BT_SECURITY_MEDIUM
)
hcon
->
pending_
sec_level
>
BT_SECURITY_MEDIUM
)
authreq
|=
SMP_AUTH_MITM
;
if
(
hcon
->
link_mode
&
HCI_LM_MASTER
)
{
...
...
@@ -932,9 +972,6 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level)
set_bit
(
SMP_FLAG_INITIATOR
,
&
smp
->
flags
);
done:
hcon
->
pending_sec_level
=
sec_level
;
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment