Commit 07f6ecec authored by David S. Miller's avatar David S. Miller

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2020-06-01

Here's one last bluetooth-next pull request for 5.8, which I hope can
still be accepted.

 - Enabled Wide-Band Speech (WBS) support for Qualcomm wcn3991
 - Multiple fixes/imprvovements to Qualcomm-based devices
 - Fix GAP/SEC/SEM/BI-10-C qualfication test case
 - Added support for Broadcom BCM4350C5 device
 - Several other smaller fixes & improvements

Please let me know if there are any issues pulling. Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1806c13d e5aeebdd
...@@ -414,11 +414,12 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = { ...@@ -414,11 +414,12 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = {
{ 0x2118, "BCM20702A0" }, /* 001.001.024 */ { 0x2118, "BCM20702A0" }, /* 001.001.024 */
{ 0x2126, "BCM4335A0" }, /* 001.001.038 */ { 0x2126, "BCM4335A0" }, /* 001.001.038 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */ { 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x230f, "BCM4354A2" }, /* 001.003.015 */ { 0x230f, "BCM4356A2" }, /* 001.003.015 */
{ 0x4106, "BCM4335B0" }, /* 002.001.006 */ { 0x4106, "BCM4335B0" }, /* 002.001.006 */
{ 0x410e, "BCM20702B0" }, /* 002.001.014 */ { 0x410e, "BCM20702B0" }, /* 002.001.014 */
{ 0x6109, "BCM4335C0" }, /* 003.001.009 */ { 0x6109, "BCM4335C0" }, /* 003.001.009 */
{ 0x610c, "BCM4354" }, /* 003.001.012 */ { 0x610c, "BCM4354" }, /* 003.001.012 */
{ 0x6607, "BCM4350C5" }, /* 003.006.007 */
{ } { }
}; };
......
...@@ -695,8 +695,7 @@ static int btmtkuart_change_baudrate(struct hci_dev *hdev) ...@@ -695,8 +695,7 @@ static int btmtkuart_change_baudrate(struct hci_dev *hdev)
/* Send a dummy byte 0xff to activate the new baudrate */ /* Send a dummy byte 0xff to activate the new baudrate */
param = 0xff; param = 0xff;
err = serdev_device_write(bdev->serdev, &param, sizeof(param), err = serdev_device_write_buf(bdev->serdev, &param, sizeof(param));
MAX_SCHEDULE_TIMEOUT);
if (err < 0 || err < sizeof(param)) if (err < 0 || err < sizeof(param))
return err; return err;
...@@ -1015,7 +1014,7 @@ static int btmtkuart_probe(struct serdev_device *serdev) ...@@ -1015,7 +1014,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
if (btmtkuart_is_standalone(bdev)) { if (btmtkuart_is_standalone(bdev)) {
err = clk_prepare_enable(bdev->osc); err = clk_prepare_enable(bdev->osc);
if (err < 0) if (err < 0)
return err; goto err_hci_free_dev;
if (bdev->boot) { if (bdev->boot) {
gpiod_set_value_cansleep(bdev->boot, 1); gpiod_set_value_cansleep(bdev->boot, 1);
...@@ -1028,10 +1027,8 @@ static int btmtkuart_probe(struct serdev_device *serdev) ...@@ -1028,10 +1027,8 @@ static int btmtkuart_probe(struct serdev_device *serdev)
/* Power on */ /* Power on */
err = regulator_enable(bdev->vcc); err = regulator_enable(bdev->vcc);
if (err < 0) { if (err < 0)
clk_disable_unprepare(bdev->osc); goto err_clk_disable_unprepare;
return err;
}
/* Reset if the reset-gpios is available otherwise the board /* Reset if the reset-gpios is available otherwise the board
* -level design should be guaranteed. * -level design should be guaranteed.
...@@ -1063,7 +1060,6 @@ static int btmtkuart_probe(struct serdev_device *serdev) ...@@ -1063,7 +1060,6 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err = hci_register_dev(hdev); err = hci_register_dev(hdev);
if (err < 0) { if (err < 0) {
dev_err(&serdev->dev, "Can't register HCI device\n"); dev_err(&serdev->dev, "Can't register HCI device\n");
hci_free_dev(hdev);
goto err_regulator_disable; goto err_regulator_disable;
} }
...@@ -1072,6 +1068,11 @@ static int btmtkuart_probe(struct serdev_device *serdev) ...@@ -1072,6 +1068,11 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err_regulator_disable: err_regulator_disable:
if (btmtkuart_is_standalone(bdev)) if (btmtkuart_is_standalone(bdev))
regulator_disable(bdev->vcc); regulator_disable(bdev->vcc);
err_clk_disable_unprepare:
if (btmtkuart_is_standalone(bdev))
clk_disable_unprepare(bdev->osc);
err_hci_free_dev:
hci_free_dev(hdev);
return err; return err;
} }
......
...@@ -74,10 +74,14 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version, ...@@ -74,10 +74,14 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version,
ver = (struct qca_btsoc_version *)(edl->data); ver = (struct qca_btsoc_version *)(edl->data);
BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id)); bt_dev_info(hdev, "QCA Product ID :0x%08x",
BT_DBG("%s: Patch :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver)); le32_to_cpu(ver->product_id));
BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rom_ver)); bt_dev_info(hdev, "QCA SOC Version :0x%08x",
BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id)); le32_to_cpu(ver->soc_id));
bt_dev_info(hdev, "QCA ROM Version :0x%08x",
le16_to_cpu(ver->rom_ver));
bt_dev_info(hdev, "QCA Patch Version:0x%08x",
le16_to_cpu(ver->patch_ver));
/* QCA chipset version can be decided by patch and SoC /* QCA chipset version can be decided by patch and SoC
* version, combination with upper 2 bytes from SoC * version, combination with upper 2 bytes from SoC
......
...@@ -75,6 +75,9 @@ enum qca_flags { ...@@ -75,6 +75,9 @@ enum qca_flags {
QCA_HW_ERROR_EVENT QCA_HW_ERROR_EVENT
}; };
enum qca_capabilities {
QCA_CAP_WIDEBAND_SPEECH = BIT(0),
};
/* HCI_IBS transmit side sleep protocol states */ /* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states { enum tx_ibs_states {
...@@ -111,6 +114,7 @@ struct qca_memdump_data { ...@@ -111,6 +114,7 @@ struct qca_memdump_data {
char *memdump_buf_tail; char *memdump_buf_tail;
u32 current_seq_no; u32 current_seq_no;
u32 received_dump; u32 received_dump;
u32 ram_dump_size;
}; };
struct qca_memdump_event_hdr { struct qca_memdump_event_hdr {
...@@ -187,10 +191,11 @@ struct qca_vreg { ...@@ -187,10 +191,11 @@ struct qca_vreg {
unsigned int load_uA; unsigned int load_uA;
}; };
struct qca_vreg_data { struct qca_device_data {
enum qca_btsoc_type soc_type; enum qca_btsoc_type soc_type;
struct qca_vreg *vregs; struct qca_vreg *vregs;
size_t num_vregs; size_t num_vregs;
uint32_t capabilities;
}; };
/* /*
...@@ -972,6 +977,8 @@ static void qca_controller_memdump(struct work_struct *work) ...@@ -972,6 +977,8 @@ static void qca_controller_memdump(struct work_struct *work)
char nullBuff[QCA_DUMP_PACKET_SIZE] = { 0 }; char nullBuff[QCA_DUMP_PACKET_SIZE] = { 0 };
u16 seq_no; u16 seq_no;
u32 dump_size; u32 dump_size;
u32 rx_size;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
while ((skb = skb_dequeue(&qca->rx_memdump_q))) { while ((skb = skb_dequeue(&qca->rx_memdump_q))) {
...@@ -1021,10 +1028,12 @@ static void qca_controller_memdump(struct work_struct *work) ...@@ -1021,10 +1028,12 @@ static void qca_controller_memdump(struct work_struct *work)
dump_size); dump_size);
queue_delayed_work(qca->workqueue, queue_delayed_work(qca->workqueue,
&qca->ctrl_memdump_timeout, &qca->ctrl_memdump_timeout,
msecs_to_jiffies(MEMDUMP_TIMEOUT_MS)); msecs_to_jiffies(MEMDUMP_TIMEOUT_MS)
);
skb_pull(skb, sizeof(dump_size)); skb_pull(skb, sizeof(dump_size));
memdump_buf = vmalloc(dump_size); memdump_buf = vmalloc(dump_size);
qca_memdump->ram_dump_size = dump_size;
qca_memdump->memdump_buf_head = memdump_buf; qca_memdump->memdump_buf_head = memdump_buf;
qca_memdump->memdump_buf_tail = memdump_buf; qca_memdump->memdump_buf_tail = memdump_buf;
} }
...@@ -1047,26 +1056,57 @@ static void qca_controller_memdump(struct work_struct *work) ...@@ -1047,26 +1056,57 @@ static void qca_controller_memdump(struct work_struct *work)
* the controller. In such cases let us store the dummy * the controller. In such cases let us store the dummy
* packets in the buffer. * packets in the buffer.
*/ */
/* For QCA6390, controller does not lost packets but
* sequence number field of packat sometimes has error
* bits, so skip this checking for missing packet.
*/
while ((seq_no > qca_memdump->current_seq_no + 1) && while ((seq_no > qca_memdump->current_seq_no + 1) &&
(soc_type != QCA_QCA6390) &&
seq_no != QCA_LAST_SEQUENCE_NUM) { seq_no != QCA_LAST_SEQUENCE_NUM) {
bt_dev_err(hu->hdev, "QCA controller missed packet:%d", bt_dev_err(hu->hdev, "QCA controller missed packet:%d",
qca_memdump->current_seq_no); qca_memdump->current_seq_no);
rx_size = qca_memdump->received_dump;
rx_size += QCA_DUMP_PACKET_SIZE;
if (rx_size > qca_memdump->ram_dump_size) {
bt_dev_err(hu->hdev,
"QCA memdump received %d, no space for missed packet",
qca_memdump->received_dump);
break;
}
memcpy(memdump_buf, nullBuff, QCA_DUMP_PACKET_SIZE); memcpy(memdump_buf, nullBuff, QCA_DUMP_PACKET_SIZE);
memdump_buf = memdump_buf + QCA_DUMP_PACKET_SIZE; memdump_buf = memdump_buf + QCA_DUMP_PACKET_SIZE;
qca_memdump->received_dump += QCA_DUMP_PACKET_SIZE; qca_memdump->received_dump += QCA_DUMP_PACKET_SIZE;
qca_memdump->current_seq_no++; qca_memdump->current_seq_no++;
} }
memcpy(memdump_buf, (unsigned char *) skb->data, skb->len); rx_size = qca_memdump->received_dump + skb->len;
if (rx_size <= qca_memdump->ram_dump_size) {
if ((seq_no != QCA_LAST_SEQUENCE_NUM) &&
(seq_no != qca_memdump->current_seq_no))
bt_dev_err(hu->hdev,
"QCA memdump unexpected packet %d",
seq_no);
bt_dev_dbg(hu->hdev,
"QCA memdump packet %d with length %d",
seq_no, skb->len);
memcpy(memdump_buf, (unsigned char *)skb->data,
skb->len);
memdump_buf = memdump_buf + skb->len; memdump_buf = memdump_buf + skb->len;
qca_memdump->memdump_buf_tail = memdump_buf; qca_memdump->memdump_buf_tail = memdump_buf;
qca_memdump->current_seq_no = seq_no + 1; qca_memdump->current_seq_no = seq_no + 1;
qca_memdump->received_dump += skb->len; qca_memdump->received_dump += skb->len;
} else {
bt_dev_err(hu->hdev,
"QCA memdump received %d, no space for packet %d",
qca_memdump->received_dump, seq_no);
}
qca->qca_memdump = qca_memdump; qca->qca_memdump = qca_memdump;
kfree_skb(skb); kfree_skb(skb);
if (seq_no == QCA_LAST_SEQUENCE_NUM) { if (seq_no == QCA_LAST_SEQUENCE_NUM) {
bt_dev_info(hu->hdev, "QCA writing crash dump of size %d bytes", bt_dev_info(hu->hdev,
qca_memdump->received_dump); "QCA memdump Done, received %d, total %d",
qca_memdump->received_dump,
qca_memdump->ram_dump_size);
memdump_buf = qca_memdump->memdump_buf_head; memdump_buf = qca_memdump->memdump_buf_head;
dev_coredumpv(&hu->serdev->dev, memdump_buf, dev_coredumpv(&hu->serdev->dev, memdump_buf,
qca_memdump->received_dump, GFP_KERNEL); qca_memdump->received_dump, GFP_KERNEL);
...@@ -1691,7 +1731,7 @@ static const struct hci_uart_proto qca_proto = { ...@@ -1691,7 +1731,7 @@ static const struct hci_uart_proto qca_proto = {
.dequeue = qca_dequeue, .dequeue = qca_dequeue,
}; };
static const struct qca_vreg_data qca_soc_data_wcn3990 = { static const struct qca_device_data qca_soc_data_wcn3990 = {
.soc_type = QCA_WCN3990, .soc_type = QCA_WCN3990,
.vregs = (struct qca_vreg []) { .vregs = (struct qca_vreg []) {
{ "vddio", 15000 }, { "vddio", 15000 },
...@@ -1702,7 +1742,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3990 = { ...@@ -1702,7 +1742,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3990 = {
.num_vregs = 4, .num_vregs = 4,
}; };
static const struct qca_vreg_data qca_soc_data_wcn3991 = { static const struct qca_device_data qca_soc_data_wcn3991 = {
.soc_type = QCA_WCN3991, .soc_type = QCA_WCN3991,
.vregs = (struct qca_vreg []) { .vregs = (struct qca_vreg []) {
{ "vddio", 15000 }, { "vddio", 15000 },
...@@ -1711,9 +1751,10 @@ static const struct qca_vreg_data qca_soc_data_wcn3991 = { ...@@ -1711,9 +1751,10 @@ static const struct qca_vreg_data qca_soc_data_wcn3991 = {
{ "vddch0", 450000 }, { "vddch0", 450000 },
}, },
.num_vregs = 4, .num_vregs = 4,
.capabilities = QCA_CAP_WIDEBAND_SPEECH,
}; };
static const struct qca_vreg_data qca_soc_data_wcn3998 = { static const struct qca_device_data qca_soc_data_wcn3998 = {
.soc_type = QCA_WCN3998, .soc_type = QCA_WCN3998,
.vregs = (struct qca_vreg []) { .vregs = (struct qca_vreg []) {
{ "vddio", 10000 }, { "vddio", 10000 },
...@@ -1724,7 +1765,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3998 = { ...@@ -1724,7 +1765,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3998 = {
.num_vregs = 4, .num_vregs = 4,
}; };
static const struct qca_vreg_data qca_soc_data_qca6390 = { static const struct qca_device_data qca_soc_data_qca6390 = {
.soc_type = QCA_QCA6390, .soc_type = QCA_QCA6390,
.num_vregs = 0, .num_vregs = 0,
}; };
...@@ -1860,7 +1901,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) ...@@ -1860,7 +1901,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
{ {
struct qca_serdev *qcadev; struct qca_serdev *qcadev;
struct hci_dev *hdev; struct hci_dev *hdev;
const struct qca_vreg_data *data; const struct qca_device_data *data;
int err; int err;
bool power_ctrl_enabled = true; bool power_ctrl_enabled = true;
...@@ -1942,12 +1983,19 @@ static int qca_serdev_probe(struct serdev_device *serdev) ...@@ -1942,12 +1983,19 @@ static int qca_serdev_probe(struct serdev_device *serdev)
} }
} }
if (power_ctrl_enabled) {
hdev = qcadev->serdev_hu.hdev; hdev = qcadev->serdev_hu.hdev;
if (power_ctrl_enabled) {
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks); set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
hdev->shutdown = qca_power_off; hdev->shutdown = qca_power_off;
} }
/* Wideband speech support must be set per driver since it can't be
* queried via hci.
*/
if (data && (data->capabilities & QCA_CAP_WIDEBAND_SPEECH))
set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks);
return 0; return 0;
} }
...@@ -1963,10 +2011,43 @@ static void qca_serdev_remove(struct serdev_device *serdev) ...@@ -1963,10 +2011,43 @@ static void qca_serdev_remove(struct serdev_device *serdev)
hci_uart_unregister_device(&qcadev->serdev_hu); hci_uart_unregister_device(&qcadev->serdev_hu);
} }
static void qca_serdev_shutdown(struct device *dev)
{
int ret;
int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
struct serdev_device *serdev = to_serdev_device(dev);
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
const u8 ibs_wake_cmd[] = { 0xFD };
const u8 edl_reset_soc_cmd[] = { 0x01, 0x00, 0xFC, 0x01, 0x05 };
if (qcadev->btsoc_type == QCA_QCA6390) {
serdev_device_write_flush(serdev);
ret = serdev_device_write_buf(serdev, ibs_wake_cmd,
sizeof(ibs_wake_cmd));
if (ret < 0) {
BT_ERR("QCA send IBS_WAKE_IND error: %d", ret);
return;
}
serdev_device_wait_until_sent(serdev, timeout);
usleep_range(8000, 10000);
serdev_device_write_flush(serdev);
ret = serdev_device_write_buf(serdev, edl_reset_soc_cmd,
sizeof(edl_reset_soc_cmd));
if (ret < 0) {
BT_ERR("QCA send EDL_RESET_REQ error: %d", ret);
return;
}
serdev_device_wait_until_sent(serdev, timeout);
usleep_range(8000, 10000);
}
}
static int __maybe_unused qca_suspend(struct device *dev) static int __maybe_unused qca_suspend(struct device *dev)
{ {
struct hci_dev *hdev = container_of(dev, struct hci_dev, dev); struct serdev_device *serdev = to_serdev_device(dev);
struct hci_uart *hu = hci_get_drvdata(hdev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct qca_data *qca = hu->priv; struct qca_data *qca = hu->priv;
unsigned long flags; unsigned long flags;
int ret = 0; int ret = 0;
...@@ -2045,8 +2126,9 @@ static int __maybe_unused qca_suspend(struct device *dev) ...@@ -2045,8 +2126,9 @@ static int __maybe_unused qca_suspend(struct device *dev)
static int __maybe_unused qca_resume(struct device *dev) static int __maybe_unused qca_resume(struct device *dev)
{ {
struct hci_dev *hdev = container_of(dev, struct hci_dev, dev); struct serdev_device *serdev = to_serdev_device(dev);
struct hci_uart *hu = hci_get_drvdata(hdev); struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct qca_data *qca = hu->priv; struct qca_data *qca = hu->priv;
clear_bit(QCA_SUSPENDING, &qca->flags); clear_bit(QCA_SUSPENDING, &qca->flags);
...@@ -2088,6 +2170,7 @@ static struct serdev_device_driver qca_serdev_driver = { ...@@ -2088,6 +2170,7 @@ static struct serdev_device_driver qca_serdev_driver = {
.name = "hci_uart_qca", .name = "hci_uart_qca",
.of_match_table = of_match_ptr(qca_bluetooth_of_match), .of_match_table = of_match_ptr(qca_bluetooth_of_match),
.acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match), .acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
.shutdown = qca_serdev_shutdown,
.pm = &qca_pm_ops, .pm = &qca_pm_ops,
}, },
}; };
......
...@@ -1381,10 +1381,26 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) ...@@ -1381,10 +1381,26 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
conn->security_cfm_cb(conn, status); conn->security_cfm_cb(conn, status);
} }
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
__u8 encrypt)
{ {
struct hci_cb *cb; struct hci_cb *cb;
__u8 encrypt;
if (conn->state == BT_CONFIG) {
if (status)
conn->state = BT_CONNECTED;
hci_connect_cfm(conn, status);
hci_conn_drop(conn);
return;
}
if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
encrypt = 0x00;
else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
encrypt = 0x02;
else
encrypt = 0x01;
if (conn->sec_level == BT_SECURITY_SDP) if (conn->sec_level == BT_SECURITY_SDP)
conn->sec_level = BT_SECURITY_LOW; conn->sec_level = BT_SECURITY_LOW;
......
...@@ -499,7 +499,7 @@ struct l2cap_ecred_conn_req { ...@@ -499,7 +499,7 @@ struct l2cap_ecred_conn_req {
__le16 mtu; __le16 mtu;
__le16 mps; __le16 mps;
__le16 credits; __le16 credits;
__le16 scid[0]; __le16 scid[];
} __packed; } __packed;
struct l2cap_ecred_conn_rsp { struct l2cap_ecred_conn_rsp {
...@@ -507,13 +507,13 @@ struct l2cap_ecred_conn_rsp { ...@@ -507,13 +507,13 @@ struct l2cap_ecred_conn_rsp {
__le16 mps; __le16 mps;
__le16 credits; __le16 credits;
__le16 result; __le16 result;
__le16 dcid[0]; __le16 dcid[];
}; };
struct l2cap_ecred_reconf_req { struct l2cap_ecred_reconf_req {
__le16 mtu; __le16 mtu;
__le16 mps; __le16 mps;
__le16 scid[0]; __le16 scid[];
} __packed; } __packed;
#define L2CAP_RECONF_SUCCESS 0x0000 #define L2CAP_RECONF_SUCCESS 0x0000
......
...@@ -225,8 +225,6 @@ static void hci_acl_create_connection(struct hci_conn *conn) ...@@ -225,8 +225,6 @@ static void hci_acl_create_connection(struct hci_conn *conn)
} }
memcpy(conn->dev_class, ie->data.dev_class, 3); memcpy(conn->dev_class, ie->data.dev_class, 3);
if (ie->data.ssp_mode > 0)
set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
} }
cp.pkt_type = cpu_to_le16(conn->pkt_type); cp.pkt_type = cpu_to_le16(conn->pkt_type);
......
...@@ -2931,7 +2931,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2931,7 +2931,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
&cp); &cp);
} else { } else {
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
hci_encrypt_cfm(conn, ev->status, 0x00); hci_encrypt_cfm(conn, ev->status);
} }
} }
...@@ -3016,22 +3016,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status, ...@@ -3016,22 +3016,7 @@ static void read_enc_key_size_complete(struct hci_dev *hdev, u8 status,
conn->enc_key_size = rp->key_size; conn->enc_key_size = rp->key_size;
} }
if (conn->state == BT_CONFIG) { hci_encrypt_cfm(conn, 0);
conn->state = BT_CONNECTED;
hci_connect_cfm(conn, 0);
hci_conn_drop(conn);
} else {
u8 encrypt;
if (!test_bit(HCI_CONN_ENCRYPT, &conn->flags))
encrypt = 0x00;
else if (test_bit(HCI_CONN_AES_CCM, &conn->flags))
encrypt = 0x02;
else
encrypt = 0x01;
hci_encrypt_cfm(conn, 0, encrypt);
}
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -3149,14 +3134,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3149,14 +3134,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
} }
notify: notify:
if (conn->state == BT_CONFIG) { hci_encrypt_cfm(conn, ev->status);
if (!ev->status)
conn->state = BT_CONNECTED;
hci_connect_cfm(conn, ev->status);
hci_conn_drop(conn);
} else
hci_encrypt_cfm(conn, ev->status, ev->encrypt);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
...@@ -4337,6 +4315,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, ...@@ -4337,6 +4315,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
case 0x11: /* Unsupported Feature or Parameter Value */ case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */ case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */ case 0x1a: /* Unsupported Remote Feature */
case 0x1e: /* Invalid LMP Parameters */
case 0x1f: /* Unspecified error */ case 0x1f: /* Unspecified error */
case 0x20: /* Unsupported LMP Parameter value */ case 0x20: /* Unsupported LMP Parameter value */
if (conn->out) { if (conn->out) {
......
...@@ -64,15 +64,13 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb) ...@@ -64,15 +64,13 @@ static void rfcomm_sk_data_ready(struct rfcomm_dlc *d, struct sk_buff *skb)
static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
{ {
struct sock *sk = d->owner, *parent; struct sock *sk = d->owner, *parent;
unsigned long flags;
if (!sk) if (!sk)
return; return;
BT_DBG("dlc %p state %ld err %d", d, d->state, err); BT_DBG("dlc %p state %ld err %d", d, d->state, err);
local_irq_save(flags); spin_lock_bh(&sk->sk_lock.slock);
bh_lock_sock(sk);
if (err) if (err)
sk->sk_err = err; sk->sk_err = err;
...@@ -93,8 +91,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err) ...@@ -93,8 +91,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
sk->sk_state_change(sk); sk->sk_state_change(sk);
} }
bh_unlock_sock(sk); spin_unlock_bh(&sk->sk_lock.slock);
local_irq_restore(flags);
if (parent && sock_flag(sk, SOCK_ZAPPED)) { if (parent && sock_flag(sk, SOCK_ZAPPED)) {
/* We have to drop DLC lock here, otherwise /* We have to drop DLC lock here, otherwise
......
...@@ -730,6 +730,10 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) ...@@ -730,6 +730,10 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
struct hci_dev *hdev = conn->hcon->hdev; struct hci_dev *hdev = conn->hcon->hdev;
struct smp_chan *smp = chan->data; struct smp_chan *smp = chan->data;
if (conn->hcon->pending_sec_level == BT_SECURITY_FIPS &&
max_key_size != SMP_MAX_ENC_KEY_SIZE)
return SMP_ENC_KEY_SIZE;
if (max_key_size > hdev->le_max_key_size || if (max_key_size > hdev->le_max_key_size ||
max_key_size < SMP_MIN_ENC_KEY_SIZE) max_key_size < SMP_MIN_ENC_KEY_SIZE)
return SMP_ENC_KEY_SIZE; return SMP_ENC_KEY_SIZE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment