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

Commit 6ea09d8a authored by David S. Miller's avatar David S. Miller
Browse files


John W. Linville says:

====================
Please pull this batch of updates for the 3.14 stream...

For the Bluetooth bits, Gustavo says:

"This is the first batch of patches intended for 3.14. There is
nothing big here.  Most of the code are refactors, clean up, small
fixes, plus some new device id support."

And...

"More patches to 3.14. Here we have the support for Low Energy
Connection Oriented Channels (LE CoC). Basically, as the name says,
this adds supports for connection oriented channels in the same way
we already have them for BR/EDR connections so profiles/protocols
that work on top of BR/EDR can now work on LE plus a plenty of new
possibilities for LE."

For the ath10k bits, Kalle says:

"Janusz and Marek implemented DFS support to ath10k, but the code is
not enabled yet due to missing cfg80211/mac80211 patches (it will be
enabled in the next pull request). Michal did some device reset fixes
and made it possible for ath10k to share an interrupt with another
device. And lots of smaller fixes from different people."

For the iwlwifi bits, Emmanuel says:

"I have here a big rework of the rate control by Eyal. This is obviously
the biggest part of this batch.
I also have enhancement of protection flags by Avri and a few bits for
WoWLAN by Eliad and Luca. Johannes cleans up the debugfs plus a few
fixes. I provided a few things for Bluetooth coexistence.
Besides this we have an implementation for low priority scan."

Along with all that, there are big batches of updates to mwifiex and
ath9k, Jeff Kirsher's FSF address fix patches, and a handful of other
bits here and there.

Please let me know if there are problems!
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents b80b376c f647a52e
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -8563,12 +8563,11 @@ S: Maintained
F:	sound/soc/codecs/twl4030*

TI WILINK WIRELESS DRIVERS
M:	Luciano Coelho <luca@coelho.fi>
L:	linux-wireless@vger.kernel.org
W:	http://wireless.kernel.org/en/users/Drivers/wl12xx
W:	http://wireless.kernel.org/en/users/Drivers/wl1251
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/luca/wl12xx.git
S:	Maintained
S:	Orphan
F:	drivers/net/wireless/ti/
F:	include/linux/wl12xx.h

+1 −1
Original line number Diff line number Diff line
@@ -269,7 +269,7 @@ static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,

#endif /* CONFIG_PM_SLEEP */

static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
static const struct pci_device_id bcma_pci_bridge_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4313) },
	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43224) },
+4 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = {
	{ USB_DEVICE(0x04CA, 0x3005) },
	{ USB_DEVICE(0x04CA, 0x3006) },
	{ USB_DEVICE(0x04CA, 0x3008) },
	{ USB_DEVICE(0x04CA, 0x300b) },
	{ USB_DEVICE(0x13d3, 0x3362) },
	{ USB_DEVICE(0x0CF3, 0xE004) },
	{ USB_DEVICE(0x0CF3, 0xE005) },
@@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = {
	{ USB_DEVICE(0x13d3, 0x3402) },
	{ USB_DEVICE(0x0cf3, 0x3121) },
	{ USB_DEVICE(0x0cf3, 0xe003) },
	{ USB_DEVICE(0x0489, 0xe05f) },

	/* Atheros AR5BBU12 with sflash firmware */
	{ USB_DEVICE(0x0489, 0xE02C) },
@@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
	{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
@@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
	{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },

	/* Atheros AR5BBU22 with sflash firmware */
	{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
+12 −13
Original line number Diff line number Diff line
@@ -23,8 +23,6 @@
#include <linux/bitops.h>
#include <linux/slab.h>
#include <net/bluetooth/bluetooth.h>
#include <linux/ctype.h>
#include <linux/firmware.h>

#define BTM_HEADER_LEN			4
#define BTM_UPLD_SIZE			2312
@@ -43,8 +41,6 @@ struct btmrvl_thread {
struct btmrvl_device {
	void *card;
	struct hci_dev *hcidev;
	struct device *dev;
	const char *cal_data;

	u8 dev_type;

@@ -90,12 +86,12 @@ struct btmrvl_private {

#define MRVL_VENDOR_PKT			0xFE

/* Bluetooth commands  */
#define BT_CMD_AUTO_SLEEP_MODE		0x23
#define BT_CMD_HOST_SLEEP_CONFIG	0x59
#define BT_CMD_HOST_SLEEP_ENABLE	0x5A
#define BT_CMD_MODULE_CFG_REQ		0x5B
#define BT_CMD_LOAD_CONFIG_DATA		0x61
/* Vendor specific Bluetooth commands */
#define BT_CMD_AUTO_SLEEP_MODE		0xFC23
#define BT_CMD_HOST_SLEEP_CONFIG	0xFC59
#define BT_CMD_HOST_SLEEP_ENABLE	0xFC5A
#define BT_CMD_MODULE_CFG_REQ		0xFC5B
#define BT_CMD_LOAD_CONFIG_DATA		0xFC61

/* Sub-commands: Module Bringup/Shutdown Request/Response */
#define MODULE_BRINGUP_REQ		0xF1
@@ -104,6 +100,11 @@ struct btmrvl_private {

#define MODULE_SHUTDOWN_REQ		0xF2

/* Vendor specific Bluetooth events */
#define BT_EVENT_AUTO_SLEEP_MODE	0x23
#define BT_EVENT_HOST_SLEEP_CONFIG	0x59
#define BT_EVENT_HOST_SLEEP_ENABLE	0x5A
#define BT_EVENT_MODULE_CFG_REQ		0x5B
#define BT_EVENT_POWER_STATE		0x20

/* Bluetooth Power States */
@@ -111,8 +112,6 @@ struct btmrvl_private {
#define BT_PS_DISABLE			0x03
#define BT_PS_SLEEP			0x01

#define OGF				0x3F

/* Host Sleep states */
#define HS_ACTIVATED			0x01
#define HS_DEACTIVATED			0x00
@@ -121,7 +120,7 @@ struct btmrvl_private {
#define PS_SLEEP			0x01
#define PS_AWAKE			0x00

#define BT_CMD_DATA_SIZE		32
#define BT_CAL_HDR_LEN			4
#define BT_CAL_DATA_SIZE		28

struct btmrvl_event {
+31 −99
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
 **/

#include <linux/module.h>

#include <linux/of.h>
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>

@@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)

	if (hdr->evt == HCI_EV_CMD_COMPLETE) {
		struct hci_ev_cmd_complete *ec;
		u16 opcode, ocf, ogf;
		u16 opcode;

		ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
		opcode = __le16_to_cpu(ec->opcode);
		ocf = hci_opcode_ocf(opcode);
		ogf = hci_opcode_ogf(opcode);

		if (priv->btmrvl_dev.sendcmdflag) {
			priv->btmrvl_dev.sendcmdflag = false;
@@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
			wake_up_interruptible(&priv->adapter->cmd_wait_q);
		}

		if (ogf == OGF) {
			BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x",
			       ogf, ocf);
		if (hci_opcode_ogf(opcode) == 0x3F) {
			BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
			kfree_skb(skb);
			return false;
		}
@@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
	}

	switch (event->data[0]) {
	case BT_CMD_AUTO_SLEEP_MODE:
	case BT_EVENT_AUTO_SLEEP_MODE:
		if (!event->data[2]) {
			if (event->data[1] == BT_PS_ENABLE)
				adapter->psmode = 1;
@@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
		}
		break;

	case BT_CMD_HOST_SLEEP_CONFIG:
	case BT_EVENT_HOST_SLEEP_CONFIG:
		if (!event->data[3])
			BT_DBG("gpio=%x, gap=%x", event->data[1],
							event->data[2]);
@@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
			BT_DBG("HSCFG command failed");
		break;

	case BT_CMD_HOST_SLEEP_ENABLE:
	case BT_EVENT_HOST_SLEEP_ENABLE:
		if (!event->data[1]) {
			adapter->hs_state = HS_ACTIVATED;
			if (adapter->psmode)
@@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
		}
		break;

	case BT_CMD_MODULE_CFG_REQ:
	case BT_EVENT_MODULE_CFG_REQ:
		if (priv->btmrvl_dev.sendcmdflag &&
				event->data[1] == MODULE_BRINGUP_REQ) {
			BT_DBG("EVENT:%s",
@@ -166,7 +163,7 @@ exit:
}
EXPORT_SYMBOL_GPL(btmrvl_process_event);

static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
				const void *param, u8 len)
{
	struct sk_buff *skb;
@@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
	}

	hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
	hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
	hdr->opcode = cpu_to_le16(opcode);
	hdr->plen = len;

	if (len)
@@ -417,127 +414,62 @@ static int btmrvl_open(struct hci_dev *hdev)
	return 0;
}

/*
 * This function parses provided calibration data input. It should contain
 * hex bytes separated by space or new line character. Here is an example.
 * 00 1C 01 37 FF FF FF FF 02 04 7F 01
 * CE BA 00 00 00 2D C6 C0 00 00 00 00
 * 00 F0 00 00
 */
static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
static int btmrvl_download_cal_data(struct btmrvl_private *priv,
				    u8 *data, int len)
{
	const u8 *s = src;
	u8 *d = dst;
	int ret;
	u8 tmp[3];

	tmp[2] = '\0';
	while ((s - src) <= len - 2) {
		if (isspace(*s)) {
			s++;
			continue;
		}

		if (isxdigit(*s)) {
			if ((d - dst) >= dst_size) {
				BT_ERR("calibration data file too big!!!");
				return -EINVAL;
			}

			memcpy(tmp, s, 2);

			ret = kstrtou8(tmp, 16, d++);
			if (ret < 0)
				return ret;

			s += 2;
		} else {
			return -EINVAL;
		}
	}
	if (d == dst)
		return -EINVAL;

	return 0;
}

static int btmrvl_load_cal_data(struct btmrvl_private *priv,
				u8 *config_data)
{
	int i, ret;
	u8 data[BT_CMD_DATA_SIZE];

	data[0] = 0x00;
	data[1] = 0x00;
	data[2] = 0x00;
	data[3] = BT_CMD_DATA_SIZE - 4;

	/* Swap cal-data bytes. Each four bytes are swapped. Considering 4
	 * byte SDIO header offset, mapping of input and output bytes will be
	 * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
	 * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
	for (i = 4; i < BT_CMD_DATA_SIZE; i++)
		data[i] = config_data[(i / 4) * 8 - 1 - i];
	data[3] = len;

	print_hex_dump_bytes("Calibration data: ",
			     DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE);
			     DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);

	ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
				   BT_CMD_DATA_SIZE);
				   BT_CAL_HDR_LEN + len);
	if (ret)
		BT_ERR("Failed to download caibration data\n");

	return 0;
}

static int
btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
{
	u8 cal_data[BT_CAL_DATA_SIZE];
	struct device_node *dt_node;
	u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
	const char name[] = "btmrvl_caldata";
	const char property[] = "btmrvl,caldata";
	int ret;

	ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
	dt_node = of_find_node_by_name(NULL, name);
	if (!dt_node)
		return -ENODEV;

	ret = of_property_read_u8_array(dt_node, property,
					cal_data + BT_CAL_HDR_LEN,
					BT_CAL_DATA_SIZE);
	if (ret)
		return ret;

	ret = btmrvl_load_cal_data(priv, cal_data);
	BT_DBG("Use cal data from device tree");
	ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
	if (ret) {
		BT_ERR("Fail to load calibrate data");
		BT_ERR("Fail to download calibrate data");
		return ret;
	}

	return 0;
}

static int btmrvl_cal_data_config(struct btmrvl_private *priv)
{
	const struct firmware *cfg;
	int ret;
	const char *cal_data = priv->btmrvl_dev.cal_data;

	if (!cal_data)
		return 0;

	ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
	if (ret < 0) {
		BT_DBG("Failed to get %s file, skipping cal data download",
		       cal_data);
		return 0;
	}

	ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
	release_firmware(cfg);
	return ret;
}

static int btmrvl_setup(struct hci_dev *hdev)
{
	struct btmrvl_private *priv = hci_get_drvdata(hdev);

	btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);

	if (btmrvl_cal_data_config(priv))
		BT_ERR("Set cal data failed");
	btmrvl_cal_data_dt(priv);

	priv->btmrvl_dev.psmode = 1;
	btmrvl_enable_ps(priv);
Loading