Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30d88ce3 authored by Kalle Valo's avatar Kalle Valo
Browse files

Merge remote-tracking branch 'wireless-next/master' into ath-next

parents c29a380e bac98320
Loading
Loading
Loading
Loading
+16 −13
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/usb.h>
#include <asm/unaligned.h>
#include <net/bluetooth/bluetooth.h>

#define VERSION "1.0"
@@ -50,12 +51,12 @@
#define ATH3K_NAME_LEN				0xFF

struct ath3k_version {
	unsigned int	rom_version;
	unsigned int	build_version;
	unsigned int	ram_version;
	unsigned char	ref_clock;
	unsigned char	reserved[0x07];
};
	__le32	rom_version;
	__le32	build_version;
	__le32	ram_version;
	__u8	ref_clock;
	__u8	reserved[7];
} __packed;

static const struct usb_device_id ath3k_table[] = {
	/* Atheros AR3011 */
@@ -349,7 +350,8 @@ static int ath3k_load_patch(struct usb_device *udev)
	unsigned char fw_state;
	char filename[ATH3K_NAME_LEN] = {0};
	const struct firmware *firmware;
	struct ath3k_version fw_version, pt_version;
	struct ath3k_version fw_version;
	__u32 pt_rom_version, pt_build_version;
	int ret;

	ret = ath3k_get_state(udev, &fw_state);
@@ -378,12 +380,13 @@ static int ath3k_load_patch(struct usb_device *udev)
		return ret;
	}

	pt_version.rom_version = *(int *)(firmware->data + firmware->size - 8);
	pt_version.build_version = *(int *)
		(firmware->data + firmware->size - 4);
	pt_rom_version = get_unaligned_le32(firmware->data +
					    firmware->size - 8);
	pt_build_version = get_unaligned_le32(firmware->data +
					      firmware->size - 4);

	if ((pt_version.rom_version != fw_version.rom_version) ||
		(pt_version.build_version <= fw_version.build_version)) {
	if (pt_rom_version != le32_to_cpu(fw_version.rom_version) ||
	    pt_build_version <= le32_to_cpu(fw_version.build_version)) {
		BT_ERR("Patch file version did not match with firmware");
		release_firmware(firmware);
		return -EINVAL;
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ struct btmrvl_private {

/* Vendor specific Bluetooth commands */
#define BT_CMD_PSCAN_WIN_REPORT_ENABLE	0xFC03
#define BT_CMD_SET_BDADDR		0xFC22
#define BT_CMD_AUTO_SLEEP_MODE		0xFC23
#define BT_CMD_HOST_SLEEP_CONFIG	0xFC59
#define BT_CMD_HOST_SLEEP_ENABLE	0xFC5A
+24 −0
Original line number Diff line number Diff line
@@ -539,6 +539,29 @@ static int btmrvl_setup(struct hci_dev *hdev)
	return 0;
}

static int btmrvl_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
{
	struct sk_buff *skb;
	long ret;
	u8 buf[8];

	buf[0] = MRVL_VENDOR_PKT;
	buf[1] = sizeof(bdaddr_t);
	memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));

	skb = __hci_cmd_sync(hdev, BT_CMD_SET_BDADDR, sizeof(buf), buf,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		ret = PTR_ERR(skb);
		BT_ERR("%s: changing btmrvl device address failed (%ld)",
		       hdev->name, ret);
		return ret;
	}
	kfree_skb(skb);

	return 0;
}

/*
 * This function handles the event generated by firmware, rx data
 * received from firmware, and tx data sent from kernel.
@@ -632,6 +655,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
	hdev->flush = btmrvl_flush;
	hdev->send  = btmrvl_send_frame;
	hdev->setup = btmrvl_setup;
	hdev->set_bdaddr = btmrvl_set_bdaddr;

	hdev->dev_type = priv->btmrvl_dev.dev_type;

+8 −8
Original line number Diff line number Diff line
@@ -1169,6 +1169,10 @@ static int btmrvl_sdio_suspend(struct device *dev)
	}

	priv = card->priv;
	hcidev = priv->btmrvl_dev.hcidev;
	BT_DBG("%s: SDIO suspend", hcidev->name);
	hci_suspend_dev(hcidev);
	skb_queue_purge(&priv->adapter->tx_queue);

	if (priv->adapter->hs_state != HS_ACTIVATED) {
		if (btmrvl_enable_hs(priv)) {
@@ -1176,10 +1180,6 @@ static int btmrvl_sdio_suspend(struct device *dev)
			return -EBUSY;
		}
	}
	hcidev = priv->btmrvl_dev.hcidev;
	BT_DBG("%s: SDIO suspend", hcidev->name);
	hci_suspend_dev(hcidev);
	skb_queue_purge(&priv->adapter->tx_queue);

	priv->adapter->is_suspended = true;

@@ -1221,13 +1221,13 @@ static int btmrvl_sdio_resume(struct device *dev)
		return 0;
	}

	priv->adapter->is_suspended = false;
	hcidev = priv->btmrvl_dev.hcidev;
	BT_DBG("%s: SDIO resume", hcidev->name);
	hci_resume_dev(hcidev);
	priv->hw_wakeup_firmware(priv);
	priv->adapter->hs_state = HS_DEACTIVATED;
	hcidev = priv->btmrvl_dev.hcidev;
	BT_DBG("%s: HS DEACTIVATED in resume!", hcidev->name);
	priv->adapter->is_suspended = false;
	BT_DBG("%s: SDIO resume", hcidev->name);
	hci_resume_dev(hcidev);

	return 0;
}
+34 −0
Original line number Diff line number Diff line
@@ -48,6 +48,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_INTEL		0x100
#define BTUSB_INTEL_BOOT	0x200
#define BTUSB_BCM_PATCHRAM	0x400
#define BTUSB_MARVELL		0x800

static const struct usb_device_id btusb_table[] = {
	/* Generic Bluetooth USB device */
@@ -113,6 +114,9 @@ static const struct usb_device_id btusb_table[] = {
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01),
	  .driver_info = BTUSB_BCM_PATCHRAM },

	/* ASUSTek Computer - Broadcom based */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x0b05, 0xff, 0x01, 0x01) },

	/* Belkin F8065bf - Broadcom based */
	{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },

@@ -242,6 +246,10 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
	{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },

	/* Marvell device */
	{ USB_DEVICE(0x1286, 0x2044), .driver_info = BTUSB_MARVELL },
	{ USB_DEVICE(0x1286, 0x2046), .driver_info = BTUSB_MARVELL },

	{ }	/* Terminating entry */
};

@@ -1455,6 +1463,29 @@ static int btusb_set_bdaddr_intel(struct hci_dev *hdev, const bdaddr_t *bdaddr)
	return 0;
}

static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
				    const bdaddr_t *bdaddr)
{
	struct sk_buff *skb;
	u8 buf[8];
	long ret;

	buf[0] = 0xfe;
	buf[1] = sizeof(bdaddr_t);
	memcpy(buf + 2, bdaddr, sizeof(bdaddr_t));

	skb = __hci_cmd_sync(hdev, 0xfc22, sizeof(buf), buf, HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		ret = PTR_ERR(skb);
		BT_ERR("%s: changing Marvell device address failed (%ld)",
		       hdev->name, ret);
		return ret;
	}
	kfree_skb(skb);

	return 0;
}

#define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}})

static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
@@ -1766,6 +1797,9 @@ static int btusb_probe(struct usb_interface *intf,
		hdev->set_bdaddr = btusb_set_bdaddr_intel;
	}

	if (id->driver_info & BTUSB_MARVELL)
		hdev->set_bdaddr = btusb_set_bdaddr_marvell;

	if (id->driver_info & BTUSB_INTEL_BOOT)
		set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);

Loading