diff options
Diffstat (limited to 'drivers/bluetooth/btusb.c')
| -rw-r--r-- | drivers/bluetooth/btusb.c | 588 | 
1 files changed, 238 insertions, 350 deletions
| diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 75c83768c257..c30d131da784 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -16,6 +16,7 @@  #include <linux/of_irq.h>  #include <linux/suspend.h>  #include <linux/gpio/consumer.h> +#include <linux/debugfs.h>  #include <asm/unaligned.h>  #include <net/bluetooth/bluetooth.h> @@ -24,13 +25,13 @@  #include "btintel.h"  #include "btbcm.h"  #include "btrtl.h" +#include "btmtk.h"  #define VERSION "0.8"  static bool disable_scofix;  static bool force_scofix;  static bool enable_autosuspend = IS_ENABLED(CONFIG_BT_HCIBTUSB_AUTOSUSPEND); -  static bool reset = true;  static struct usb_driver btusb_driver; @@ -59,6 +60,7 @@ static struct usb_driver btusb_driver;  #define BTUSB_WIDEBAND_SPEECH	0x400000  #define BTUSB_VALID_LE_STATES   0x800000  #define BTUSB_QCA_WCN6855	0x1000000 +#define BTUSB_INTEL_BROKEN_SHUTDOWN_LED	0x2000000  #define BTUSB_INTEL_BROKEN_INITIAL_NCMD 0x4000000  static const struct usb_device_id btusb_table[] = { @@ -295,6 +297,24 @@ static const struct usb_device_id blacklist_table[] = {  	{ USB_DEVICE(0x0cf3, 0xe600), .driver_info = BTUSB_QCA_WCN6855 |  						     BTUSB_WIDEBAND_SPEECH |  						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x0489, 0xe0cc), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x0489, 0xe0d6), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x0489, 0xe0e3), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x10ab, 0x9309), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x10ab, 0x9409), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x0489, 0xe0d0), .driver_info = BTUSB_QCA_WCN6855 | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES },  	/* Broadcom BCM2035 */  	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 }, @@ -365,10 +385,13 @@ static const struct usb_device_id blacklist_table[] = {  	{ USB_DEVICE(0x8087, 0x0033), .driver_info = BTUSB_INTEL_COMBINED },  	{ USB_DEVICE(0x8087, 0x07da), .driver_info = BTUSB_CSR },  	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL_COMBINED | -						     BTUSB_INTEL_BROKEN_INITIAL_NCMD }, -	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED }, +						     BTUSB_INTEL_BROKEN_INITIAL_NCMD | +						     BTUSB_INTEL_BROKEN_SHUTDOWN_LED }, +	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL_COMBINED | +						     BTUSB_INTEL_BROKEN_SHUTDOWN_LED },  	{ USB_DEVICE(0x8087, 0x0a2b), .driver_info = BTUSB_INTEL_COMBINED }, -	{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED }, +	{ USB_DEVICE(0x8087, 0x0aa7), .driver_info = BTUSB_INTEL_COMBINED | +						     BTUSB_INTEL_BROKEN_SHUTDOWN_LED },  	{ USB_DEVICE(0x8087, 0x0aaa), .driver_info = BTUSB_INTEL_COMBINED },  	/* Other Intel Bluetooth devices */ @@ -384,6 +407,8 @@ static const struct usb_device_id blacklist_table[] = {  	/* Realtek 8852AE Bluetooth devices */  	{ USB_DEVICE(0x0bda, 0xc852), .driver_info = BTUSB_REALTEK |  						     BTUSB_WIDEBAND_SPEECH }, +	{ USB_DEVICE(0x0bda, 0x385a), .driver_info = BTUSB_REALTEK | +						     BTUSB_WIDEBAND_SPEECH },  	{ USB_DEVICE(0x0bda, 0x4852), .driver_info = BTUSB_REALTEK |  						     BTUSB_WIDEBAND_SPEECH },  	{ USB_DEVICE(0x04c5, 0x165c), .driver_info = BTUSB_REALTEK | @@ -423,6 +448,14 @@ static const struct usb_device_id blacklist_table[] = {  						     BTUSB_WIDEBAND_SPEECH |  						     BTUSB_VALID_LE_STATES }, +	/* MediaTek MT7922A Bluetooth devices */ +	{ USB_DEVICE(0x0489, 0xe0d8), .driver_info = BTUSB_MEDIATEK | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +	{ USB_DEVICE(0x0489, 0xe0d9), .driver_info = BTUSB_MEDIATEK | +						     BTUSB_WIDEBAND_SPEECH | +						     BTUSB_VALID_LE_STATES }, +  	/* Additional Realtek 8723AE Bluetooth devices */  	{ USB_DEVICE(0x0930, 0x021d), .driver_info = BTUSB_REALTEK },  	{ USB_DEVICE(0x13d3, 0x3394), .driver_info = BTUSB_REALTEK }, @@ -549,8 +582,13 @@ struct btusb_data {  	unsigned long flags; -	struct work_struct work; -	struct work_struct waker; +	bool poll_sync; +	int intr_interval; +	struct work_struct  work; +	struct work_struct  waker; +	struct delayed_work rx_work; + +	struct sk_buff_head acl_q;  	struct usb_anchor deferred;  	struct usb_anchor tx_anchor; @@ -715,6 +753,16 @@ static inline void btusb_free_frags(struct btusb_data *data)  	spin_unlock_irqrestore(&data->rxlock, flags);  } +static int btusb_recv_event(struct btusb_data *data, struct sk_buff *skb) +{ +	if (data->intr_interval) { +		/* Trigger dequeue immediatelly if an event is received */ +		schedule_delayed_work(&data->rx_work, 0); +	} + +	return data->recv_event(data->hdev, skb); +} +  static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)  {  	struct sk_buff *skb; @@ -760,7 +808,7 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)  		if (!hci_skb_expect(skb)) {  			/* Complete frame */ -			data->recv_event(data->hdev, skb); +			btusb_recv_event(data, skb);  			skb = NULL;  		}  	} @@ -771,6 +819,20 @@ static int btusb_recv_intr(struct btusb_data *data, void *buffer, int count)  	return err;  } +static int btusb_recv_acl(struct btusb_data *data, struct sk_buff *skb) +{ +	/* Only queue ACL packet if intr_interval is set as it means +	 * force_poll_sync has been enabled. +	 */ +	if (!data->intr_interval) +		return data->recv_acl(data->hdev, skb); + +	skb_queue_tail(&data->acl_q, skb); +	schedule_delayed_work(&data->rx_work, data->intr_interval); + +	return 0; +} +  static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)  {  	struct sk_buff *skb; @@ -818,7 +880,7 @@ static int btusb_recv_bulk(struct btusb_data *data, void *buffer, int count)  		if (!hci_skb_expect(skb)) {  			/* Complete frame */ -			data->recv_acl(data->hdev, skb); +			btusb_recv_acl(data, skb);  			skb = NULL;  		}  	} @@ -924,6 +986,8 @@ static void btusb_intr_complete(struct urb *urb)  		if (err != -EPERM && err != -ENODEV)  			bt_dev_err(hdev, "urb %p failed to resubmit (%d)",  				   urb, -err); +		if (err != -EPERM) +			hci_cmd_sync_cancel(hdev, -err);  		usb_unanchor_urb(urb);  	}  } @@ -967,9 +1031,33 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags)  		if (err != -EPERM && err != -ENODEV)  			bt_dev_err(hdev, "urb %p submission failed (%d)",  				   urb, -err); +		if (err != -EPERM) +			hci_cmd_sync_cancel(hdev, -err);  		usb_unanchor_urb(urb);  	} +	/* Only initialize intr_interval if URB poll sync is enabled */ +	if (!data->poll_sync) +		goto done; + +	/* The units are frames (milliseconds) for full and low speed devices, +	 * and microframes (1/8 millisecond) for highspeed and SuperSpeed +	 * devices. +	 * +	 * This is done once on open/resume so it shouldn't change even if +	 * force_poll_sync changes. +	 */ +	switch (urb->dev->speed) { +	case USB_SPEED_SUPER_PLUS: +	case USB_SPEED_SUPER:	/* units are 125us */ +		data->intr_interval = usecs_to_jiffies(urb->interval * 125); +		break; +	default: +		data->intr_interval = msecs_to_jiffies(urb->interval); +		break; +	} + +done:  	usb_free_urb(urb);  	return err; @@ -1322,10 +1410,13 @@ static void btusb_tx_complete(struct urb *urb)  	if (!test_bit(HCI_RUNNING, &hdev->flags))  		goto done; -	if (!urb->status) +	if (!urb->status) {  		hdev->stat.byte_tx += urb->transfer_buffer_length; -	else +	} else { +		if (hci_skb_pkt_type(skb) == HCI_COMMAND_PKT) +			hci_cmd_sync_cancel(hdev, -urb->status);  		hdev->stat.err_tx++; +	}  done:  	spin_lock_irqsave(&data->txlock, flags); @@ -1429,9 +1520,12 @@ static int btusb_close(struct hci_dev *hdev)  	BT_DBG("%s", hdev->name); +	cancel_delayed_work(&data->rx_work);  	cancel_work_sync(&data->work);  	cancel_work_sync(&data->waker); +	skb_queue_purge(&data->acl_q); +  	clear_bit(BTUSB_ISOC_RUNNING, &data->flags);  	clear_bit(BTUSB_BULK_RUNNING, &data->flags);  	clear_bit(BTUSB_INTR_RUNNING, &data->flags); @@ -1463,6 +1557,10 @@ static int btusb_flush(struct hci_dev *hdev)  	BT_DBG("%s", hdev->name); +	cancel_delayed_work(&data->rx_work); + +	skb_queue_purge(&data->acl_q); +  	usb_kill_anchored_urbs(&data->tx_anchor);  	btusb_free_frags(data); @@ -1826,6 +1924,17 @@ static void btusb_waker(struct work_struct *work)  	usb_autopm_put_interface(data->intf);  } +static void btusb_rx_work(struct work_struct *work) +{ +	struct btusb_data *data = container_of(work, struct btusb_data, +					       rx_work.work); +	struct sk_buff *skb; + +	/* Dequeue ACL data received during the interval */ +	while ((skb = skb_dequeue(&data->acl_q))) +		data->recv_acl(data->hdev, skb); +} +  static int btusb_setup_bcm92035(struct hci_dev *hdev)  {  	struct sk_buff *skb; @@ -2131,122 +2240,6 @@ static int btusb_send_frame_intel(struct hci_dev *hdev, struct sk_buff *skb)  #define MTK_BT_RST_DONE		0x00000100  #define MTK_BT_RESET_WAIT_MS	100  #define MTK_BT_RESET_NUM_TRIES	10 -#define FIRMWARE_MT7663		"mediatek/mt7663pr2h.bin" -#define FIRMWARE_MT7668		"mediatek/mt7668pr2h.bin" - -#define HCI_WMT_MAX_EVENT_SIZE		64 -/* It is for mt79xx download rom patch*/ -#define MTK_FW_ROM_PATCH_HEADER_SIZE	32 -#define MTK_FW_ROM_PATCH_GD_SIZE	64 -#define MTK_FW_ROM_PATCH_SEC_MAP_SIZE	64 -#define MTK_SEC_MAP_COMMON_SIZE	12 -#define MTK_SEC_MAP_NEED_SEND_SIZE	52 - -enum { -	BTMTK_WMT_PATCH_DWNLD = 0x1, -	BTMTK_WMT_FUNC_CTRL = 0x6, -	BTMTK_WMT_RST = 0x7, -	BTMTK_WMT_SEMAPHORE = 0x17, -}; - -enum { -	BTMTK_WMT_INVALID, -	BTMTK_WMT_PATCH_UNDONE, -	BTMTK_WMT_PATCH_PROGRESS, -	BTMTK_WMT_PATCH_DONE, -	BTMTK_WMT_ON_UNDONE, -	BTMTK_WMT_ON_DONE, -	BTMTK_WMT_ON_PROGRESS, -}; - -struct btmtk_wmt_hdr { -	u8	dir; -	u8	op; -	__le16	dlen; -	u8	flag; -} __packed; - -struct btmtk_hci_wmt_cmd { -	struct btmtk_wmt_hdr hdr; -	u8 data[]; -} __packed; - -struct btmtk_hci_wmt_evt { -	struct hci_event_hdr hhdr; -	struct btmtk_wmt_hdr whdr; -} __packed; - -struct btmtk_hci_wmt_evt_funcc { -	struct btmtk_hci_wmt_evt hwhdr; -	__be16 status; -} __packed; - -struct btmtk_tci_sleep { -	u8 mode; -	__le16 duration; -	__le16 host_duration; -	u8 host_wakeup_pin; -	u8 time_compensation; -} __packed; - -struct btmtk_hci_wmt_params { -	u8 op; -	u8 flag; -	u16 dlen; -	const void *data; -	u32 *status; -}; - -struct btmtk_patch_header { -	u8 datetime[16]; -	u8 platform[4]; -	__le16 hwver; -	__le16 swver; -	__le32 magicnum; -} __packed; - -struct btmtk_global_desc { -	__le32 patch_ver; -	__le32 sub_sys; -	__le32 feature_opt; -	__le32 section_num; -} __packed; - -struct btmtk_section_map { -	__le32 sectype; -	__le32 secoffset; -	__le32 secsize; -	union { -		__le32 u4SecSpec[13]; -		struct { -			__le32 dlAddr; -			__le32 dlsize; -			__le32 seckeyidx; -			__le32 alignlen; -			__le32 sectype; -			__le32 dlmodecrctype; -			__le32 crc; -			__le32 reserved[6]; -		} bin_info_spec; -	}; -} __packed; - -static int btusb_set_bdaddr_mtk(struct hci_dev *hdev, const bdaddr_t *bdaddr) -{ -	struct sk_buff *skb; -	long ret; - -	skb = __hci_cmd_sync(hdev, 0xfc1a, sizeof(bdaddr), bdaddr, HCI_INIT_TIMEOUT); -	if (IS_ERR(skb)) { -		ret = PTR_ERR(skb); -		bt_dev_err(hdev, "changing Mediatek device address failed (%ld)", -			   ret); -		return ret; -	} -	kfree_skb(skb); - -	return 0; -}  static void btusb_mtk_wmt_recv(struct urb *urb)  { @@ -2265,6 +2258,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)  		skb = bt_skb_alloc(HCI_WMT_MAX_EVENT_SIZE, GFP_ATOMIC);  		if (!skb) {  			hdev->stat.err_rx++; +			kfree(urb->setup_packet);  			return;  		} @@ -2285,6 +2279,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)  			data->evt_skb = skb_clone(skb, GFP_ATOMIC);  			if (!data->evt_skb) {  				kfree_skb(skb); +				kfree(urb->setup_packet);  				return;  			}  		} @@ -2293,6 +2288,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)  		if (err < 0) {  			kfree_skb(data->evt_skb);  			data->evt_skb = NULL; +			kfree(urb->setup_packet);  			return;  		} @@ -2303,6 +2299,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)  			wake_up_bit(&data->flags,  				    BTUSB_TX_WAIT_VND_EVT);  		} +		kfree(urb->setup_packet);  		return;  	} else if (urb->status == -ENOENT) {  		/* Avoid suspend failed when usb_kill_urb */ @@ -2323,6 +2320,7 @@ static void btusb_mtk_wmt_recv(struct urb *urb)  	usb_anchor_urb(urb, &data->ctrl_anchor);  	err = usb_submit_urb(urb, GFP_ATOMIC);  	if (err < 0) { +		kfree(urb->setup_packet);  		/* -EPERM: urb is being killed;  		 * -ENODEV: device got disconnected  		 */ @@ -2497,209 +2495,6 @@ err_free_wc:  	return err;  } -static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname) -{ -	struct btmtk_hci_wmt_params wmt_params; -	struct btmtk_global_desc *globaldesc = NULL; -	struct btmtk_section_map *sectionmap; -	const struct firmware *fw; -	const u8 *fw_ptr; -	const u8 *fw_bin_ptr; -	int err, dlen, i, status; -	u8 flag, first_block, retry; -	u32 section_num, dl_size, section_offset; -	u8 cmd[64]; - -	err = request_firmware(&fw, fwname, &hdev->dev); -	if (err < 0) { -		bt_dev_err(hdev, "Failed to load firmware file (%d)", err); -		return err; -	} - -	fw_ptr = fw->data; -	fw_bin_ptr = fw_ptr; -	globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE); -	section_num = le32_to_cpu(globaldesc->section_num); - -	for (i = 0; i < section_num; i++) { -		first_block = 1; -		fw_ptr = fw_bin_ptr; -		sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE + -			      MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i); - -		section_offset = le32_to_cpu(sectionmap->secoffset); -		dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize); - -		if (dl_size > 0) { -			retry = 20; -			while (retry > 0) { -				cmd[0] = 0; /* 0 means legacy dl mode. */ -				memcpy(cmd + 1, -				       fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE + -				       MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i + -				       MTK_SEC_MAP_COMMON_SIZE, -				       MTK_SEC_MAP_NEED_SEND_SIZE + 1); - -				wmt_params.op = BTMTK_WMT_PATCH_DWNLD; -				wmt_params.status = &status; -				wmt_params.flag = 0; -				wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1; -				wmt_params.data = &cmd; - -				err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); -				if (err < 0) { -					bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", -						   err); -					goto err_release_fw; -				} - -				if (status == BTMTK_WMT_PATCH_UNDONE) { -					break; -				} else if (status == BTMTK_WMT_PATCH_PROGRESS) { -					msleep(100); -					retry--; -				} else if (status == BTMTK_WMT_PATCH_DONE) { -					goto next_section; -				} else { -					bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)", -						   status); -					goto err_release_fw; -				} -			} - -			fw_ptr += section_offset; -			wmt_params.op = BTMTK_WMT_PATCH_DWNLD; -			wmt_params.status = NULL; - -			while (dl_size > 0) { -				dlen = min_t(int, 250, dl_size); -				if (first_block == 1) { -					flag = 1; -					first_block = 0; -				} else if (dl_size - dlen <= 0) { -					flag = 3; -				} else { -					flag = 2; -				} - -				wmt_params.flag = flag; -				wmt_params.dlen = dlen; -				wmt_params.data = fw_ptr; - -				err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); -				if (err < 0) { -					bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", -						   err); -					goto err_release_fw; -				} - -				dl_size -= dlen; -				fw_ptr += dlen; -			} -		} -next_section: -		continue; -	} -	/* Wait a few moments for firmware activation done */ -	usleep_range(100000, 120000); - -err_release_fw: -	release_firmware(fw); - -	return err; -} - -static int btusb_mtk_setup_firmware(struct hci_dev *hdev, const char *fwname) -{ -	struct btmtk_hci_wmt_params wmt_params; -	const struct firmware *fw; -	const u8 *fw_ptr; -	size_t fw_size; -	int err, dlen; -	u8 flag, param; - -	err = request_firmware(&fw, fwname, &hdev->dev); -	if (err < 0) { -		bt_dev_err(hdev, "Failed to load firmware file (%d)", err); -		return err; -	} - -	/* Power on data RAM the firmware relies on. */ -	param = 1; -	wmt_params.op = BTMTK_WMT_FUNC_CTRL; -	wmt_params.flag = 3; -	wmt_params.dlen = sizeof(param); -	wmt_params.data = ¶m; -	wmt_params.status = NULL; - -	err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); -	if (err < 0) { -		bt_dev_err(hdev, "Failed to power on data RAM (%d)", err); -		goto err_release_fw; -	} - -	fw_ptr = fw->data; -	fw_size = fw->size; - -	/* The size of patch header is 30 bytes, should be skip */ -	if (fw_size < 30) { -		err = -EINVAL; -		goto err_release_fw; -	} - -	fw_size -= 30; -	fw_ptr += 30; -	flag = 1; - -	wmt_params.op = BTMTK_WMT_PATCH_DWNLD; -	wmt_params.status = NULL; - -	while (fw_size > 0) { -		dlen = min_t(int, 250, fw_size); - -		/* Tell device the position in sequence */ -		if (fw_size - dlen <= 0) -			flag = 3; -		else if (fw_size < fw->size - 30) -			flag = 2; - -		wmt_params.flag = flag; -		wmt_params.dlen = dlen; -		wmt_params.data = fw_ptr; - -		err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); -		if (err < 0) { -			bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)", -				   err); -			goto err_release_fw; -		} - -		fw_size -= dlen; -		fw_ptr += dlen; -	} - -	wmt_params.op = BTMTK_WMT_RST; -	wmt_params.flag = 4; -	wmt_params.dlen = 0; -	wmt_params.data = NULL; -	wmt_params.status = NULL; - -	/* Activate funciton the firmware providing to */ -	err = btusb_mtk_hci_wmt_sync(hdev, &wmt_params); -	if (err < 0) { -		bt_dev_err(hdev, "Failed to send wmt rst (%d)", err); -		goto err_release_fw; -	} - -	/* Wait a few moments for firmware activation done */ -	usleep_range(10000, 12000); - -err_release_fw: -	release_firmware(fw); - -	return err; -} -  static int btusb_mtk_func_query(struct hci_dev *hdev)  {  	struct btmtk_hci_wmt_params wmt_params; @@ -2857,7 +2652,12 @@ static int btusb_mtk_setup(struct hci_dev *hdev)  		snprintf(fw_bin_name, sizeof(fw_bin_name),  			"mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin",  			 dev_id & 0xffff, (fw_version & 0xff) + 1); -		err = btusb_mtk_setup_firmware_79xx(hdev, fw_bin_name); +		err = btmtk_setup_firmware_79xx(hdev, fw_bin_name, +						btusb_mtk_hci_wmt_sync); +		if (err < 0) { +			bt_dev_err(hdev, "Failed to set up firmware (%d)", err); +			return err; +		}  		/* It's Device EndPoint Reset Option Register */  		btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); @@ -2877,6 +2677,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)  		}  		hci_set_msft_opcode(hdev, 0xFD30); +		hci_set_aosp_capable(hdev);  		goto done;  	default:  		bt_dev_err(hdev, "Unsupported hardware variant (%08x)", @@ -2903,7 +2704,8 @@ static int btusb_mtk_setup(struct hci_dev *hdev)  	}  	/* Setup a firmware which the device definitely requires */ -	err = btusb_mtk_setup_firmware(hdev, fwname); +	err = btmtk_setup_firmware(hdev, fwname, +				   btusb_mtk_hci_wmt_sync);  	if (err < 0)  		return err; @@ -3064,9 +2866,6 @@ static int btusb_recv_acl_mtk(struct hci_dev *hdev, struct sk_buff *skb)  	return hci_recv_frame(hdev, skb);  } -MODULE_FIRMWARE(FIRMWARE_MT7663); -MODULE_FIRMWARE(FIRMWARE_MT7668); -  #ifdef CONFIG_PM  /* Configure an out-of-band gpio as wake-up pin, if specified in device tree */  static int marvell_config_oob_wake(struct hci_dev *hdev) @@ -3190,11 +2989,15 @@ static int btusb_set_bdaddr_wcn6855(struct hci_dev *hdev,  #define QCA_DFU_TIMEOUT		3000  #define QCA_FLAG_MULTI_NVM      0x80 +#define WCN6855_2_0_RAM_VERSION_GF 0x400c1200 +#define WCN6855_2_1_RAM_VERSION_GF 0x400c1211 +  struct qca_version {  	__le32	rom_version;  	__le32	patch_version;  	__le32	ram_version; -	__le16	board_id; +	__u8	chip_id; +	__u8	platform_id;  	__le16	flag;  	__u8	reserved[4];  } __packed; @@ -3221,6 +3024,7 @@ static const struct qca_device_info qca_devices_table[] = {  	{ 0x00000302, 28, 4, 16 }, /* Rome 3.2 */  	{ 0x00130100, 40, 4, 16 }, /* WCN6855 1.0 */  	{ 0x00130200, 40, 4, 16 }, /* WCN6855 2.0 */ +	{ 0x00130201, 40, 4, 16 }, /* WCN6855 2.1 */  };  static int btusb_qca_send_vendor_req(struct usb_device *udev, u8 request, @@ -3375,6 +3179,50 @@ done:  	return err;  } +static void btusb_generate_qca_nvm_name(char *fwname, size_t max_size, +					const struct qca_version *ver) +{ +	u32 rom_version = le32_to_cpu(ver->rom_version); +	u16 flag = le16_to_cpu(ver->flag); + +	if (((flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) { +		/* The board_id should be split into two bytes +		 * The 1st byte is chip ID, and the 2nd byte is platform ID +		 * For example, board ID 0x010A, 0x01 is platform ID. 0x0A is chip ID +		 * we have several platforms, and platform IDs are continuously added +		 * Platform ID: +		 * 0x00 is for Mobile +		 * 0x01 is for X86 +		 * 0x02 is for Automotive +		 * 0x03 is for Consumer electronic +		 */ +		u16 board_id = (ver->chip_id << 8) + ver->platform_id; +		const char *variant; + +		switch (le32_to_cpu(ver->ram_version)) { +		case WCN6855_2_0_RAM_VERSION_GF: +		case WCN6855_2_1_RAM_VERSION_GF: +			variant = "_gf"; +			break; +		default: +			variant = ""; +			break; +		} + +		if (board_id == 0) { +			snprintf(fwname, max_size, "qca/nvm_usb_%08x%s.bin", +				rom_version, variant); +		} else { +			snprintf(fwname, max_size, "qca/nvm_usb_%08x%s_%04x.bin", +				rom_version, variant, board_id); +		} +	} else { +		snprintf(fwname, max_size, "qca/nvm_usb_%08x.bin", +			rom_version); +	} + +} +  static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,  				    struct qca_version *ver,  				    const struct qca_device_info *info) @@ -3383,20 +3231,7 @@ static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,  	char fwname[64];  	int err; -	if (((ver->flag >> 8) & 0xff) == QCA_FLAG_MULTI_NVM) { -		/* if boardid equal 0, use default nvm without surfix */ -		if (le16_to_cpu(ver->board_id) == 0x0) { -			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin", -				 le32_to_cpu(ver->rom_version)); -		} else { -			snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x_%04x.bin", -				le32_to_cpu(ver->rom_version), -				le16_to_cpu(ver->board_id)); -		} -	} else { -		snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin", -			 le32_to_cpu(ver->rom_version)); -	} +	btusb_generate_qca_nvm_name(fwname, sizeof(fwname), ver);  	err = request_firmware(&fw, fwname, &hdev->dev);  	if (err) { @@ -3661,6 +3496,49 @@ static int btusb_shutdown_qca(struct hci_dev *hdev)  	return 0;  } +static ssize_t force_poll_sync_read(struct file *file, char __user *user_buf, +				    size_t count, loff_t *ppos) +{ +	struct btusb_data *data = file->private_data; +	char buf[3]; + +	buf[0] = data->poll_sync ? 'Y' : 'N'; +	buf[1] = '\n'; +	buf[2] = '\0'; +	return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t force_poll_sync_write(struct file *file, +				     const char __user *user_buf, +				     size_t count, loff_t *ppos) +{ +	struct btusb_data *data = file->private_data; +	bool enable; +	int err; + +	err = kstrtobool_from_user(user_buf, count, &enable); +	if (err) +		return err; + +	/* Only allow changes while the adapter is down */ +	if (test_bit(HCI_UP, &data->hdev->flags)) +		return -EPERM; + +	if (data->poll_sync == enable) +		return -EALREADY; + +	data->poll_sync = enable; + +	return count; +} + +static const struct file_operations force_poll_sync_fops = { +	.open		= simple_open, +	.read		= force_poll_sync_read, +	.write		= force_poll_sync_write, +	.llseek		= default_llseek, +}; +  static int btusb_probe(struct usb_interface *intf,  		       const struct usb_device_id *id)  { @@ -3744,6 +3622,10 @@ static int btusb_probe(struct usb_interface *intf,  	INIT_WORK(&data->work, btusb_work);  	INIT_WORK(&data->waker, btusb_waker); +	INIT_DELAYED_WORK(&data->rx_work, btusb_rx_work); + +	skb_queue_head_init(&data->acl_q); +  	init_usb_anchor(&data->deferred);  	init_usb_anchor(&data->tx_anchor);  	spin_lock_init(&data->txlock); @@ -3857,6 +3739,9 @@ static int btusb_probe(struct usb_interface *intf,  		if (id->driver_info & BTUSB_INTEL_BROKEN_INITIAL_NCMD)  			btintel_set_flag(hdev, INTEL_BROKEN_INITIAL_NCMD); + +		if (id->driver_info & BTUSB_INTEL_BROKEN_SHUTDOWN_LED) +			btintel_set_flag(hdev, INTEL_BROKEN_SHUTDOWN_LED);  	}  	if (id->driver_info & BTUSB_MARVELL) @@ -3868,7 +3753,7 @@ static int btusb_probe(struct usb_interface *intf,  		hdev->shutdown = btusb_mtk_shutdown;  		hdev->manufacturer = 70;  		hdev->cmd_timeout = btusb_mtk_cmd_timeout; -		hdev->set_bdaddr = btusb_set_bdaddr_mtk; +		hdev->set_bdaddr = btmtk_set_bdaddr;  		set_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks);  		data->recv_acl = btusb_recv_acl_mtk;  	} @@ -4009,6 +3894,9 @@ static int btusb_probe(struct usb_interface *intf,  	usb_set_intfdata(intf, data); +	debugfs_create_file("force_poll_sync", 0644, hdev->debugfs, data, +			    &force_poll_sync_fops); +  	return 0;  out_free_dev: |