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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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 */
	{ }
};

+9 −8
Original line number Diff line number Diff line
@@ -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;
}
+9 −5
Original line number Diff line number Diff line
@@ -74,10 +74,14 @@ 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
+103 −20
Original line number Diff line number Diff line
@@ -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) &&
		       (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);
		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)
		}
	}

	if (power_ctrl_enabled) {
	hdev = qcadev->serdev_hu.hdev;

	if (power_ctrl_enabled) {
		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,
	},
};
+18 −2
Original line number Diff line number Diff line
@@ -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;
Loading