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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2020-06-01 11:01:09 -07:00
commit 07f6ecec65
10 changed files with 154 additions and 71 deletions

View File

@ -414,11 +414,12 @@ static const struct bcm_subver_table bcm_usb_subver_table[] = {
{ 0x2118, "BCM20702A0" }, /* 001.001.024 */
{ 0x2126, "BCM4335A0" }, /* 001.001.038 */
{ 0x220e, "BCM20702A1" }, /* 001.002.014 */
{ 0x230f, "BCM4354A2" }, /* 001.003.015 */
{ 0x230f, "BCM4356A2" }, /* 001.003.015 */
{ 0x4106, "BCM4335B0" }, /* 002.001.006 */
{ 0x410e, "BCM20702B0" }, /* 002.001.014 */
{ 0x6109, "BCM4335C0" }, /* 003.001.009 */
{ 0x610c, "BCM4354" }, /* 003.001.012 */
{ 0x6607, "BCM4350C5" }, /* 003.006.007 */
{ }
};

View File

@ -695,8 +695,7 @@ static int btmtkuart_change_baudrate(struct hci_dev *hdev)
/* Send a dummy byte 0xff to activate the new baudrate */
param = 0xff;
err = serdev_device_write(bdev->serdev, &param, sizeof(param),
MAX_SCHEDULE_TIMEOUT);
err = serdev_device_write_buf(bdev->serdev, &param, sizeof(param));
if (err < 0 || err < sizeof(param))
return err;
@ -1015,7 +1014,7 @@ static int btmtkuart_probe(struct serdev_device *serdev)
if (btmtkuart_is_standalone(bdev)) {
err = clk_prepare_enable(bdev->osc);
if (err < 0)
return err;
goto err_hci_free_dev;
if (bdev->boot) {
gpiod_set_value_cansleep(bdev->boot, 1);
@ -1028,10 +1027,8 @@ static int btmtkuart_probe(struct serdev_device *serdev)
/* Power on */
err = regulator_enable(bdev->vcc);
if (err < 0) {
clk_disable_unprepare(bdev->osc);
return err;
}
if (err < 0)
goto err_clk_disable_unprepare;
/* Reset if the reset-gpios is available otherwise the board
* -level design should be guaranteed.
@ -1063,7 +1060,6 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err = hci_register_dev(hdev);
if (err < 0) {
dev_err(&serdev->dev, "Can't register HCI device\n");
hci_free_dev(hdev);
goto err_regulator_disable;
}
@ -1072,6 +1068,11 @@ static int btmtkuart_probe(struct serdev_device *serdev)
err_regulator_disable:
if (btmtkuart_is_standalone(bdev))
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;
}

View File

@ -74,17 +74,21 @@ int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version,
ver = (struct qca_btsoc_version *)(edl->data);
BT_DBG("%s: Product:0x%08x", hdev->name, le32_to_cpu(ver->product_id));
BT_DBG("%s: Patch :0x%08x", hdev->name, le16_to_cpu(ver->patch_ver));
BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rom_ver));
BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id));
bt_dev_info(hdev, "QCA Product ID :0x%08x",
le32_to_cpu(ver->product_id));
bt_dev_info(hdev, "QCA SOC Version :0x%08x",
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
* version, combination with upper 2 bytes from SoC
* and lower 2 bytes from patch will be used.
*/
*soc_version = (le32_to_cpu(ver->soc_id) << 16) |
(le16_to_cpu(ver->rom_ver) & 0x0000ffff);
(le16_to_cpu(ver->rom_ver) & 0x0000ffff);
if (*soc_version == 0)
err = -EILSEQ;

View File

@ -75,6 +75,9 @@ enum qca_flags {
QCA_HW_ERROR_EVENT
};
enum qca_capabilities {
QCA_CAP_WIDEBAND_SPEECH = BIT(0),
};
/* HCI_IBS transmit side sleep protocol states */
enum tx_ibs_states {
@ -111,6 +114,7 @@ struct qca_memdump_data {
char *memdump_buf_tail;
u32 current_seq_no;
u32 received_dump;
u32 ram_dump_size;
};
struct qca_memdump_event_hdr {
@ -187,10 +191,11 @@ struct qca_vreg {
unsigned int load_uA;
};
struct qca_vreg_data {
struct qca_device_data {
enum qca_btsoc_type soc_type;
struct qca_vreg *vregs;
size_t num_vregs;
uint32_t capabilities;
};
/*
@ -972,6 +977,8 @@ static void qca_controller_memdump(struct work_struct *work)
char nullBuff[QCA_DUMP_PACKET_SIZE] = { 0 };
u16 seq_no;
u32 dump_size;
u32 rx_size;
enum qca_btsoc_type soc_type = qca_soc_type(hu);
while ((skb = skb_dequeue(&qca->rx_memdump_q))) {
@ -1021,10 +1028,12 @@ static void qca_controller_memdump(struct work_struct *work)
dump_size);
queue_delayed_work(qca->workqueue,
&qca->ctrl_memdump_timeout,
msecs_to_jiffies(MEMDUMP_TIMEOUT_MS));
msecs_to_jiffies(MEMDUMP_TIMEOUT_MS)
);
skb_pull(skb, sizeof(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_tail = memdump_buf;
}
@ -1047,26 +1056,57 @@ static void qca_controller_memdump(struct work_struct *work)
* the controller. In such cases let us store the dummy
* 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) &&
seq_no != QCA_LAST_SEQUENCE_NUM) {
(soc_type != QCA_QCA6390) &&
seq_no != QCA_LAST_SEQUENCE_NUM) {
bt_dev_err(hu->hdev, "QCA controller missed packet:%d",
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);
memdump_buf = memdump_buf + QCA_DUMP_PACKET_SIZE;
qca_memdump->received_dump += QCA_DUMP_PACKET_SIZE;
qca_memdump->current_seq_no++;
}
memcpy(memdump_buf, (unsigned char *) skb->data, skb->len);
memdump_buf = memdump_buf + skb->len;
qca_memdump->memdump_buf_tail = memdump_buf;
qca_memdump->current_seq_no = seq_no + 1;
qca_memdump->received_dump += 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;
qca_memdump->memdump_buf_tail = memdump_buf;
qca_memdump->current_seq_no = seq_no + 1;
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;
kfree_skb(skb);
if (seq_no == QCA_LAST_SEQUENCE_NUM) {
bt_dev_info(hu->hdev, "QCA writing crash dump of size %d bytes",
qca_memdump->received_dump);
bt_dev_info(hu->hdev,
"QCA memdump Done, received %d, total %d",
qca_memdump->received_dump,
qca_memdump->ram_dump_size);
memdump_buf = qca_memdump->memdump_buf_head;
dev_coredumpv(&hu->serdev->dev, memdump_buf,
qca_memdump->received_dump, GFP_KERNEL);
@ -1691,7 +1731,7 @@ static const struct hci_uart_proto qca_proto = {
.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,
.vregs = (struct qca_vreg []) {
{ "vddio", 15000 },
@ -1702,7 +1742,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3990 = {
.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,
.vregs = (struct qca_vreg []) {
{ "vddio", 15000 },
@ -1711,9 +1751,10 @@ static const struct qca_vreg_data qca_soc_data_wcn3991 = {
{ "vddch0", 450000 },
},
.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,
.vregs = (struct qca_vreg []) {
{ "vddio", 10000 },
@ -1724,7 +1765,7 @@ static const struct qca_vreg_data qca_soc_data_wcn3998 = {
.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,
.num_vregs = 0,
};
@ -1860,7 +1901,7 @@ static int qca_serdev_probe(struct serdev_device *serdev)
{
struct qca_serdev *qcadev;
struct hci_dev *hdev;
const struct qca_vreg_data *data;
const struct qca_device_data *data;
int err;
bool power_ctrl_enabled = true;
@ -1942,12 +1983,19 @@ static int qca_serdev_probe(struct serdev_device *serdev)
}
}
hdev = qcadev->serdev_hu.hdev;
if (power_ctrl_enabled) {
hdev = qcadev->serdev_hu.hdev;
set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);
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;
}
@ -1963,10 +2011,43 @@ static void qca_serdev_remove(struct serdev_device *serdev)
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)
{
struct hci_dev *hdev = container_of(dev, struct hci_dev, dev);
struct hci_uart *hu = hci_get_drvdata(hdev);
struct serdev_device *serdev = to_serdev_device(dev);
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct qca_data *qca = hu->priv;
unsigned long flags;
int ret = 0;
@ -2045,8 +2126,9 @@ error:
static int __maybe_unused qca_resume(struct device *dev)
{
struct hci_dev *hdev = container_of(dev, struct hci_dev, dev);
struct hci_uart *hu = hci_get_drvdata(hdev);
struct serdev_device *serdev = to_serdev_device(dev);
struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
struct hci_uart *hu = &qcadev->serdev_hu;
struct qca_data *qca = hu->priv;
clear_bit(QCA_SUSPENDING, &qca->flags);
@ -2088,6 +2170,7 @@ static struct serdev_device_driver qca_serdev_driver = {
.name = "hci_uart_qca",
.of_match_table = of_match_ptr(qca_bluetooth_of_match),
.acpi_match_table = ACPI_PTR(qca_bluetooth_acpi_match),
.shutdown = qca_serdev_shutdown,
.pm = &qca_pm_ops,
},
};

View File

@ -1381,10 +1381,26 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
conn->security_cfm_cb(conn, status);
}
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status,
__u8 encrypt)
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
{
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)
conn->sec_level = BT_SECURITY_LOW;

View File

@ -499,7 +499,7 @@ struct l2cap_ecred_conn_req {
__le16 mtu;
__le16 mps;
__le16 credits;
__le16 scid[0];
__le16 scid[];
} __packed;
struct l2cap_ecred_conn_rsp {
@ -507,13 +507,13 @@ struct l2cap_ecred_conn_rsp {
__le16 mps;
__le16 credits;
__le16 result;
__le16 dcid[0];
__le16 dcid[];
};
struct l2cap_ecred_reconf_req {
__le16 mtu;
__le16 mps;
__le16 scid[0];
__le16 scid[];
} __packed;
#define L2CAP_RECONF_SUCCESS 0x0000

View File

@ -225,8 +225,6 @@ static void hci_acl_create_connection(struct hci_conn *conn)
}
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);

View File

@ -2931,7 +2931,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
&cp);
} else {
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,
conn->enc_key_size = rp->key_size;
}
if (conn->state == BT_CONFIG) {
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);
}
hci_encrypt_cfm(conn, 0);
unlock:
hci_dev_unlock(hdev);
@ -3149,14 +3134,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
}
notify:
if (conn->state == BT_CONFIG) {
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);
hci_encrypt_cfm(conn, ev->status);
unlock:
hci_dev_unlock(hdev);
@ -4337,6 +4315,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
case 0x11: /* Unsupported Feature or Parameter Value */
case 0x1c: /* SCO interval rejected */
case 0x1a: /* Unsupported Remote Feature */
case 0x1e: /* Invalid LMP Parameters */
case 0x1f: /* Unspecified error */
case 0x20: /* Unsupported LMP Parameter value */
if (conn->out) {

View File

@ -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)
{
struct sock *sk = d->owner, *parent;
unsigned long flags;
if (!sk)
return;
BT_DBG("dlc %p state %ld err %d", d, d->state, err);
local_irq_save(flags);
bh_lock_sock(sk);
spin_lock_bh(&sk->sk_lock.slock);
if (err)
sk->sk_err = err;
@ -93,8 +91,7 @@ static void rfcomm_sk_state_change(struct rfcomm_dlc *d, int err)
sk->sk_state_change(sk);
}
bh_unlock_sock(sk);
local_irq_restore(flags);
spin_unlock_bh(&sk->sk_lock.slock);
if (parent && sock_flag(sk, SOCK_ZAPPED)) {
/* We have to drop DLC lock here, otherwise

View File

@ -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 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 ||
max_key_size < SMP_MIN_ENC_KEY_SIZE)
return SMP_ENC_KEY_SIZE;