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

Commit 5f1764dd 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:

====================
Here's another set of Bluetooth & ieee802154 patches intended for 4.1:

 - Added support for QCA ROME chipset family in the btusb driver
 - at86rf230 driver fixes & cleanups
 - ieee802154 cleanups
 - Refactoring of Bluetooth mgmt API to allow new users
 - New setting for static Bluetooth address exposed to user space
 - Refactoring of hci_dev flags to remove limit of 32
 - Remove unnecessary fast-connectable setting usage restrictions
 - Fix behavior to be consistent when trying to pair already paired device
 - Service discovery corner-case fixes

Please let me know if there are any issues pulling. Thanks.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2801be4a b6d595e3
Loading
Loading
Loading
Loading
+301 −32
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ static struct usb_driver btusb_driver;
#define BTUSB_SWAVE		0x1000
#define BTUSB_SWAVE		0x1000
#define BTUSB_INTEL_NEW		0x2000
#define BTUSB_INTEL_NEW		0x2000
#define BTUSB_AMP		0x4000
#define BTUSB_AMP		0x4000
#define BTUSB_QCA_ROME		0x8000


static const struct usb_device_id btusb_table[] = {
static const struct usb_device_id btusb_table[] = {
	/* Generic Bluetooth USB device */
	/* Generic Bluetooth USB device */
@@ -213,6 +214,10 @@ static const struct usb_device_id blacklist_table[] = {
	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe036), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },
	{ USB_DEVICE(0x0489, 0xe03c), .driver_info = BTUSB_ATH3012 },


	/* QCA ROME chipset */
	{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME},
	{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME},

	/* Broadcom BCM2035 */
	/* Broadcom BCM2035 */
	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
	{ USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU },
@@ -338,6 +343,8 @@ struct btusb_data {


	int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb);
	int (*recv_event)(struct hci_dev *hdev, struct sk_buff *skb);
	int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);
	int (*recv_bulk)(struct btusb_data *data, void *buffer, int count);

	int (*setup_on_usb)(struct hci_dev *hdev);
};
};


static inline void btusb_free_frags(struct btusb_data *data)
static inline void btusb_free_frags(struct btusb_data *data)
@@ -879,6 +886,15 @@ static int btusb_open(struct hci_dev *hdev)


	BT_DBG("%s", hdev->name);
	BT_DBG("%s", hdev->name);


	/* Patching USB firmware files prior to starting any URBs of HCI path
	 * It is more safe to use USB bulk channel for downloading USB patch
	 */
	if (data->setup_on_usb) {
		err = data->setup_on_usb(hdev);
		if (err <0)
			return err;
	}

	err = usb_autopm_get_interface(data->intf);
	err = usb_autopm_get_interface(data->intf);
	if (err < 0)
	if (err < 0)
		return err;
		return err;
@@ -1254,6 +1270,28 @@ static void btusb_waker(struct work_struct *work)
	usb_autopm_put_interface(data->intf);
	usb_autopm_put_interface(data->intf);
}
}


static struct sk_buff *btusb_read_local_version(struct hci_dev *hdev)
{
	struct sk_buff *skb;

	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
		       hdev->name, PTR_ERR(skb));
		return skb;
	}

	if (skb->len != sizeof(struct hci_rp_read_local_version)) {
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
		       hdev->name);
		kfree_skb(skb);
		return ERR_PTR(-EIO);
	}

	return skb;
}

static int btusb_setup_bcm92035(struct hci_dev *hdev)
static int btusb_setup_bcm92035(struct hci_dev *hdev)
{
{
	struct sk_buff *skb;
	struct sk_buff *skb;
@@ -1278,12 +1316,9 @@ static int btusb_setup_csr(struct hci_dev *hdev)


	BT_DBG("%s", hdev->name);
	BT_DBG("%s", hdev->name);


	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
	skb = btusb_read_local_version(hdev);
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb))
	if (IS_ERR(skb)) {
		BT_ERR("Reading local version failed (%ld)", -PTR_ERR(skb));
		return -PTR_ERR(skb);
		return -PTR_ERR(skb);
	}


	rp = (struct hci_rp_read_local_version *)skb->data;
	rp = (struct hci_rp_read_local_version *)skb->data;


@@ -2414,21 +2449,9 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
	kfree_skb(skb);
	kfree_skb(skb);


	/* Read Local Version Info */
	/* Read Local Version Info */
	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
	skb = btusb_read_local_version(hdev);
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb))
	if (IS_ERR(skb)) {
		return PTR_ERR(skb);
		ret = PTR_ERR(skb);
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
		       hdev->name, ret);
		return ret;
	}

	if (skb->len != sizeof(*ver)) {
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
		       hdev->name);
		kfree_skb(skb);
		return -EIO;
	}


	ver = (struct hci_rp_read_local_version *)skb->data;
	ver = (struct hci_rp_read_local_version *)skb->data;
	rev = le16_to_cpu(ver->hci_rev);
	rev = le16_to_cpu(ver->hci_rev);
@@ -2516,20 +2539,9 @@ static int btusb_setup_bcm_patchram(struct hci_dev *hdev)
	kfree_skb(skb);
	kfree_skb(skb);


	/* Read Local Version Info */
	/* Read Local Version Info */
	skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL,
	skb = btusb_read_local_version(hdev);
			     HCI_INIT_TIMEOUT);
	if (IS_ERR(skb)) {
	if (IS_ERR(skb)) {
		ret = PTR_ERR(skb);
		ret = PTR_ERR(skb);
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION failed (%ld)",
		       hdev->name, ret);
		goto done;
	}

	if (skb->len != sizeof(*ver)) {
		BT_ERR("%s: HCI_OP_READ_LOCAL_VERSION event length mismatch",
		       hdev->name);
		kfree_skb(skb);
		ret = -EIO;
		goto done;
		goto done;
	}
	}


@@ -2628,6 +2640,258 @@ static int btusb_set_bdaddr_ath3012(struct hci_dev *hdev,
	return 0;
	return 0;
}
}


#define QCA_DFU_PACKET_LEN	4096

#define QCA_GET_TARGET_VERSION	0x09
#define QCA_CHECK_STATUS	0x05
#define QCA_DFU_DOWNLOAD	0x01

#define QCA_SYSCFG_UPDATED	0x40
#define QCA_PATCH_UPDATED	0x80
#define QCA_DFU_TIMEOUT		3000

struct qca_version {
	__le32	rom_version;
	__le32	patch_version;
	__le32	ram_version;
	__le32	ref_clock;
	__u8	reserved[4];
} __packed;

struct qca_rampatch_version {
	__le16	rom_version;
	__le16	patch_version;
} __packed;

struct qca_device_info {
	u32	rom_version;
	u8	rampatch_hdr;	/* length of header in rampatch */
	u8	nvm_hdr;	/* length of header in NVM */
	u8	ver_offset;	/* offset of version structure in rampatch */
};

static const struct qca_device_info qca_devices_table[] = {
	{ 0x00000100, 20, 4, 10 }, /* Rome 1.0 */
	{ 0x00000101, 20, 4, 10 }, /* Rome 1.1 */
	{ 0x00000201, 28, 4, 18 }, /* Rome 2.1 */
	{ 0x00000300, 28, 4, 18 }, /* Rome 3.0 */
	{ 0x00000302, 28, 4, 18 }, /* Rome 3.2 */
};

static int btusb_qca_send_vendor_req(struct hci_dev *hdev, u8 request,
				     void *data, u16 size)
{
	struct btusb_data *btdata = hci_get_drvdata(hdev);
	struct usb_device *udev = btdata->udev;
	int pipe, err;
	u8 *buf;

	buf = kmalloc(size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	/* Found some of USB hosts have IOT issues with ours so that we should
	 * not wait until HCI layer is ready.
	 */
	pipe = usb_rcvctrlpipe(udev, 0);
	err = usb_control_msg(udev, pipe, request, USB_TYPE_VENDOR | USB_DIR_IN,
			      0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
	if (err < 0) {
		BT_ERR("%s: Failed to access otp area (%d)", hdev->name, err);
		goto done;
	}

	memcpy(data, buf, size);

done:
	kfree(buf);

	return err;
}

static int btusb_setup_qca_download_fw(struct hci_dev *hdev,
				       const struct firmware *firmware,
				       size_t hdr_size)
{
	struct btusb_data *btdata = hci_get_drvdata(hdev);
	struct usb_device *udev = btdata->udev;
	size_t count, size, sent = 0;
	int pipe, len, err;
	u8 *buf;

	buf = kmalloc(QCA_DFU_PACKET_LEN, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	count = firmware->size;

	size = min_t(size_t, count, hdr_size);
	memcpy(buf, firmware->data, size);

	/* USB patches should go down to controller through USB path
	 * because binary format fits to go down through USB channel.
	 * USB control path is for patching headers and USB bulk is for
	 * patch body.
	 */
	pipe = usb_sndctrlpipe(udev, 0);
	err = usb_control_msg(udev, pipe, QCA_DFU_DOWNLOAD, USB_TYPE_VENDOR,
			      0, 0, buf, size, USB_CTRL_SET_TIMEOUT);
	if (err < 0) {
		BT_ERR("%s: Failed to send headers (%d)", hdev->name, err);
		goto done;
	}

	sent += size;
	count -= size;

	while (count) {
		size = min_t(size_t, count, QCA_DFU_PACKET_LEN);

		memcpy(buf, firmware->data + sent, size);

		pipe = usb_sndbulkpipe(udev, 0x02);
		err = usb_bulk_msg(udev, pipe, buf, size, &len,
				   QCA_DFU_TIMEOUT);
		if (err < 0) {
			BT_ERR("%s: Failed to send body at %zd of %zd (%d)",
			       hdev->name, sent, firmware->size, err);
			break;
		}

		if (size != len) {
			BT_ERR("%s: Failed to get bulk buffer", hdev->name);
			err = -EILSEQ;
			break;
		}

		sent  += size;
		count -= size;
	}

done:
	kfree(buf);
	return err;
}

static int btusb_setup_qca_load_rampatch(struct hci_dev *hdev,
					 struct qca_version *ver,
					 const struct qca_device_info *info)
{
	struct qca_rampatch_version *rver;
	const struct firmware *fw;
	u32 ver_rom, ver_patch;
	u16 rver_rom, rver_patch;
	char fwname[64];
	int err;

	ver_rom = le32_to_cpu(ver->rom_version);
	ver_patch = le32_to_cpu(ver->patch_version);

	snprintf(fwname, sizeof(fwname), "qca/rampatch_usb_%08x.bin", ver_rom);

	err = request_firmware(&fw, fwname, &hdev->dev);
	if (err) {
		BT_ERR("%s: failed to request rampatch file: %s (%d)",
		       hdev->name, fwname, err);
		return err;
	}

	BT_INFO("%s: using rampatch file: %s", hdev->name, fwname);

	rver = (struct qca_rampatch_version *)(fw->data + info->ver_offset);
	rver_rom = le16_to_cpu(rver->rom_version);
	rver_patch = le16_to_cpu(rver->patch_version);

	BT_INFO("%s: QCA: patch rome 0x%x build 0x%x, firmware rome 0x%x "
		"build 0x%x", hdev->name, rver_rom, rver_patch, ver_rom,
		ver_patch);

	if (rver_rom != ver_rom || rver_patch <= ver_patch) {
		BT_ERR("%s: rampatch file version did not match with firmware",
		       hdev->name);
		err = -EINVAL;
		goto done;
	}

	err = btusb_setup_qca_download_fw(hdev, fw, info->rampatch_hdr);

done:
	release_firmware(fw);

	return err;
}

static int btusb_setup_qca_load_nvm(struct hci_dev *hdev,
				    struct qca_version *ver,
				    const struct qca_device_info *info)
{
	const struct firmware *fw;
	char fwname[64];
	int err;

	snprintf(fwname, sizeof(fwname), "qca/nvm_usb_%08x.bin",
		 le32_to_cpu(ver->rom_version));

	err = request_firmware(&fw, fwname, &hdev->dev);
	if (err) {
		BT_ERR("%s: failed to request NVM file: %s (%d)",
		       hdev->name, fwname, err);
		return err;
	}

	BT_INFO("%s: using NVM file: %s", hdev->name, fwname);

	err = btusb_setup_qca_download_fw(hdev, fw, info->nvm_hdr);

	release_firmware(fw);

	return err;
}

static int btusb_setup_qca(struct hci_dev *hdev)
{
	const struct qca_device_info *info = NULL;
	struct qca_version ver;
	u32 ver_rom;
	u8 status;
	int i, err;

	err = btusb_qca_send_vendor_req(hdev, QCA_GET_TARGET_VERSION, &ver,
				        sizeof(ver));
	if (err < 0)
		return err;

	ver_rom = le32_to_cpu(ver.rom_version);
	for (i = 0; i < ARRAY_SIZE(qca_devices_table); i++) {
		if (ver_rom == qca_devices_table[i].rom_version)
			info = &qca_devices_table[i];
	}
	if (!info) {
		BT_ERR("%s: don't support firmware rome 0x%x", hdev->name,
		       ver_rom);
		return -ENODEV;
	}

	err = btusb_qca_send_vendor_req(hdev, QCA_CHECK_STATUS, &status,
					sizeof(status));
	if (err < 0)
		return err;

	if (!(status & QCA_PATCH_UPDATED)) {
		err = btusb_setup_qca_load_rampatch(hdev, &ver, info);
		if (err < 0)
			return err;
	}

	if (!(status & QCA_SYSCFG_UPDATED)) {
		err = btusb_setup_qca_load_nvm(hdev, &ver, info);
		if (err < 0)
			return err;
	}

	return 0;
}

static int btusb_probe(struct usb_interface *intf,
static int btusb_probe(struct usb_interface *intf,
		       const struct usb_device_id *id)
		       const struct usb_device_id *id)
{
{
@@ -2781,6 +3045,11 @@ static int btusb_probe(struct usb_interface *intf,
		set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
		set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks);
	}
	}


	if (id->driver_info & BTUSB_QCA_ROME) {
		data->setup_on_usb = btusb_setup_qca;
		hdev->set_bdaddr = btusb_set_bdaddr_ath3012;
	}

	if (id->driver_info & BTUSB_AMP) {
	if (id->driver_info & BTUSB_AMP) {
		/* AMP controllers do not support SCO packets */
		/* AMP controllers do not support SCO packets */
		data->isoc = NULL;
		data->isoc = NULL;
+154 −72
Original line number Original line Diff line number Diff line
@@ -19,6 +19,8 @@
 */
 */
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/hrtimer.h>
#include <linux/jiffies.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/gpio.h>
@@ -53,10 +55,20 @@ struct at86rf2xx_chip_data {
};
};


#define AT86RF2XX_MAX_BUF		(127 + 3)
#define AT86RF2XX_MAX_BUF		(127 + 3)
/* tx retries to access the TX_ON state
 * if it's above then force change will be started.
 *
 * We assume the max_frame_retries (7) value of 802.15.4 here.
 */
#define AT86RF2XX_MAX_TX_RETRIES	7
/* We use the recommended 5 minutes timeout to recalibrate */
#define AT86RF2XX_CAL_LOOP_TIMEOUT	(5 * 60 * HZ)


struct at86rf230_state_change {
struct at86rf230_state_change {
	struct at86rf230_local *lp;
	struct at86rf230_local *lp;
	int irq;


	struct hrtimer timer;
	struct spi_message msg;
	struct spi_message msg;
	struct spi_transfer trx;
	struct spi_transfer trx;
	u8 buf[AT86RF2XX_MAX_BUF];
	u8 buf[AT86RF2XX_MAX_BUF];
@@ -81,10 +93,12 @@ struct at86rf230_local {
	struct at86rf230_state_change irq;
	struct at86rf230_state_change irq;


	bool tx_aret;
	bool tx_aret;
	unsigned long cal_timeout;
	s8 max_frame_retries;
	s8 max_frame_retries;
	bool is_tx;
	bool is_tx;
	/* spinlock for is_tx protection */
	/* spinlock for is_tx protection */
	spinlock_t lock;
	spinlock_t lock;
	u8 tx_retry;
	struct sk_buff *tx_skb;
	struct sk_buff *tx_skb;
	struct at86rf230_state_change tx;
	struct at86rf230_state_change tx;
};
};
@@ -407,6 +421,8 @@ at86rf230_reg_volatile(struct device *dev, unsigned int reg)
	case RG_PHY_ED_LEVEL:
	case RG_PHY_ED_LEVEL:
	case RG_IRQ_STATUS:
	case RG_IRQ_STATUS:
	case RG_VREG_CTRL:
	case RG_VREG_CTRL:
	case RG_PLL_CF:
	case RG_PLL_DCU:
		return true;
		return true;
	default:
	default:
		return false;
		return false;
@@ -470,18 +486,25 @@ at86rf230_async_read_reg(struct at86rf230_local *lp, const u8 reg,
	u8 *tx_buf = ctx->buf;
	u8 *tx_buf = ctx->buf;


	tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
	tx_buf[0] = (reg & CMD_REG_MASK) | CMD_REG;
	ctx->trx.len = 2;
	ctx->msg.complete = complete;
	ctx->msg.complete = complete;
	ctx->irq_enable = irq_enable;
	ctx->irq_enable = irq_enable;
	rc = spi_async(lp->spi, &ctx->msg);
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
	if (rc) {
		if (irq_enable)
		if (irq_enable)
			enable_irq(lp->spi->irq);
			enable_irq(ctx->irq);


		at86rf230_async_error(lp, ctx, rc);
		at86rf230_async_error(lp, ctx, rc);
	}
	}
}
}


static inline u8 at86rf230_state_to_force(u8 state)
{
	if (state == STATE_TX_ON)
		return STATE_FORCE_TX_ON;
	else
		return STATE_FORCE_TRX_OFF;
}

static void
static void
at86rf230_async_state_assert(void *context)
at86rf230_async_state_assert(void *context)
{
{
@@ -512,10 +535,21 @@ at86rf230_async_state_assert(void *context)
			 * in STATE_BUSY_RX_AACK, we run a force state change
			 * in STATE_BUSY_RX_AACK, we run a force state change
			 * to STATE_TX_ON. This is a timeout handling, if the
			 * to STATE_TX_ON. This is a timeout handling, if the
			 * transceiver stucks in STATE_BUSY_RX_AACK.
			 * transceiver stucks in STATE_BUSY_RX_AACK.
			 *
			 * Additional we do several retries to try to get into
			 * TX_ON state without forcing. If the retries are
			 * higher or equal than AT86RF2XX_MAX_TX_RETRIES we
			 * will do a force change.
			 */
			 */
			if (ctx->to_state == STATE_TX_ON) {
			if (ctx->to_state == STATE_TX_ON ||
				at86rf230_async_state_change(lp, ctx,
			    ctx->to_state == STATE_TRX_OFF) {
							     STATE_FORCE_TX_ON,
				u8 state = ctx->to_state;

				if (lp->tx_retry >= AT86RF2XX_MAX_TX_RETRIES)
					state = at86rf230_state_to_force(state);
				lp->tx_retry++;

				at86rf230_async_state_change(lp, ctx, state,
							     ctx->complete,
							     ctx->complete,
							     ctx->irq_enable);
							     ctx->irq_enable);
				return;
				return;
@@ -531,6 +565,19 @@ at86rf230_async_state_assert(void *context)
		ctx->complete(context);
		ctx->complete(context);
}
}


static enum hrtimer_restart at86rf230_async_state_timer(struct hrtimer *timer)
{
	struct at86rf230_state_change *ctx =
		container_of(timer, struct at86rf230_state_change, timer);
	struct at86rf230_local *lp = ctx->lp;

	at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
				 at86rf230_async_state_assert,
				 ctx->irq_enable);

	return HRTIMER_NORESTART;
}

/* Do state change timing delay. */
/* Do state change timing delay. */
static void
static void
at86rf230_async_state_delay(void *context)
at86rf230_async_state_delay(void *context)
@@ -539,6 +586,7 @@ at86rf230_async_state_delay(void *context)
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf2xx_chip_data *c = lp->data;
	struct at86rf2xx_chip_data *c = lp->data;
	bool force = false;
	bool force = false;
	ktime_t tim;


	/* The force state changes are will show as normal states in the
	/* The force state changes are will show as normal states in the
	 * state status subregister. We change the to_state to the
	 * state status subregister. We change the to_state to the
@@ -562,11 +610,15 @@ at86rf230_async_state_delay(void *context)
	case STATE_TRX_OFF:
	case STATE_TRX_OFF:
		switch (ctx->to_state) {
		switch (ctx->to_state) {
		case STATE_RX_AACK_ON:
		case STATE_RX_AACK_ON:
			usleep_range(c->t_off_to_aack, c->t_off_to_aack + 10);
			tim = ktime_set(0, c->t_off_to_aack * NSEC_PER_USEC);
			goto change;
			goto change;
		case STATE_TX_ON:
		case STATE_TX_ON:
			usleep_range(c->t_off_to_tx_on,
			tim = ktime_set(0, c->t_off_to_tx_on * NSEC_PER_USEC);
				     c->t_off_to_tx_on + 10);
			/* state change from TRX_OFF to TX_ON to do a
			 * calibration, we need to reset the timeout for the
			 * next one.
			 */
			lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
			goto change;
			goto change;
		default:
		default:
			break;
			break;
@@ -574,14 +626,15 @@ at86rf230_async_state_delay(void *context)
		break;
		break;
	case STATE_BUSY_RX_AACK:
	case STATE_BUSY_RX_AACK:
		switch (ctx->to_state) {
		switch (ctx->to_state) {
		case STATE_TRX_OFF:
		case STATE_TX_ON:
		case STATE_TX_ON:
			/* Wait for worst case receiving time if we
			/* Wait for worst case receiving time if we
			 * didn't make a force change from BUSY_RX_AACK
			 * didn't make a force change from BUSY_RX_AACK
			 * to TX_ON.
			 * to TX_ON or TRX_OFF.
			 */
			 */
			if (!force) {
			if (!force) {
				usleep_range(c->t_frame + c->t_p_ack,
				tim = ktime_set(0, (c->t_frame + c->t_p_ack) *
					     c->t_frame + c->t_p_ack + 1000);
						   NSEC_PER_USEC);
				goto change;
				goto change;
			}
			}
			break;
			break;
@@ -593,7 +646,7 @@ at86rf230_async_state_delay(void *context)
	case STATE_P_ON:
	case STATE_P_ON:
		switch (ctx->to_state) {
		switch (ctx->to_state) {
		case STATE_TRX_OFF:
		case STATE_TRX_OFF:
			usleep_range(c->t_reset_to_off, c->t_reset_to_off + 10);
			tim = ktime_set(0, c->t_reset_to_off * NSEC_PER_USEC);
			goto change;
			goto change;
		default:
		default:
			break;
			break;
@@ -604,12 +657,10 @@ at86rf230_async_state_delay(void *context)
	}
	}


	/* Default delay is 1us in the most cases */
	/* Default delay is 1us in the most cases */
	udelay(1);
	tim = ktime_set(0, NSEC_PER_USEC);


change:
change:
	at86rf230_async_read_reg(lp, RG_TRX_STATUS, ctx,
	hrtimer_start(&ctx->timer, tim, HRTIMER_MODE_REL);
				 at86rf230_async_state_assert,
				 ctx->irq_enable);
}
}


static void
static void
@@ -645,12 +696,11 @@ at86rf230_async_state_change_start(void *context)
	 */
	 */
	buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
	buf[0] = (RG_TRX_STATE & CMD_REG_MASK) | CMD_REG | CMD_WRITE;
	buf[1] = ctx->to_state;
	buf[1] = ctx->to_state;
	ctx->trx.len = 2;
	ctx->msg.complete = at86rf230_async_state_delay;
	ctx->msg.complete = at86rf230_async_state_delay;
	rc = spi_async(lp->spi, &ctx->msg);
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
	if (rc) {
		if (ctx->irq_enable)
		if (ctx->irq_enable)
			enable_irq(lp->spi->irq);
			enable_irq(ctx->irq);


		at86rf230_async_error(lp, ctx, rc);
		at86rf230_async_error(lp, ctx, rc);
	}
	}
@@ -708,11 +758,10 @@ at86rf230_tx_complete(void *context)
{
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;
	struct sk_buff *skb = lp->tx_skb;


	enable_irq(lp->spi->irq);
	enable_irq(ctx->irq);


	ieee802154_xmit_complete(lp->hw, skb, !lp->tx_aret);
	ieee802154_xmit_complete(lp->hw, lp->tx_skb, !lp->tx_aret);
}
}


static void
static void
@@ -721,7 +770,7 @@ at86rf230_tx_on(void *context)
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;


	at86rf230_async_state_change(lp, &lp->irq, STATE_RX_AACK_ON,
	at86rf230_async_state_change(lp, ctx, STATE_RX_AACK_ON,
				     at86rf230_tx_complete, true);
				     at86rf230_tx_complete, true);
}
}


@@ -765,14 +814,25 @@ at86rf230_tx_trac_status(void *context)
}
}


static void
static void
at86rf230_rx(struct at86rf230_local *lp,
at86rf230_rx_read_frame_complete(void *context)
	     const u8 *data, const u8 len, const u8 lqi)
{
{
	struct sk_buff *skb;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	u8 rx_local_buf[AT86RF2XX_MAX_BUF];
	u8 rx_local_buf[AT86RF2XX_MAX_BUF];
	const u8 *buf = ctx->buf;
	struct sk_buff *skb;
	u8 len, lqi;


	memcpy(rx_local_buf, data, len);
	len = buf[1];
	enable_irq(lp->spi->irq);
	if (!ieee802154_is_valid_psdu_len(len)) {
		dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
		len = IEEE802154_MTU;
	}
	lqi = buf[2 + len];

	memcpy(rx_local_buf, buf + 2, len);
	ctx->trx.len = 2;
	enable_irq(ctx->irq);


	skb = dev_alloc_skb(IEEE802154_MTU);
	skb = dev_alloc_skb(IEEE802154_MTU);
	if (!skb) {
	if (!skb) {
@@ -785,51 +845,34 @@ at86rf230_rx(struct at86rf230_local *lp,
}
}


static void
static void
at86rf230_rx_read_frame_complete(void *context)
at86rf230_rx_read_frame(void *context)
{
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;
	const u8 *buf = lp->irq.buf;
	u8 *buf = ctx->buf;
	u8 len = buf[1];

	if (!ieee802154_is_valid_psdu_len(len)) {
		dev_vdbg(&lp->spi->dev, "corrupted frame received\n");
		len = IEEE802154_MTU;
	}

	at86rf230_rx(lp, buf + 2, len, buf[2 + len]);
}

static void
at86rf230_rx_read_frame(struct at86rf230_local *lp)
{
	int rc;
	int rc;


	u8 *buf = lp->irq.buf;

	buf[0] = CMD_FB;
	buf[0] = CMD_FB;
	lp->irq.trx.len = AT86RF2XX_MAX_BUF;
	ctx->trx.len = AT86RF2XX_MAX_BUF;
	lp->irq.msg.complete = at86rf230_rx_read_frame_complete;
	ctx->msg.complete = at86rf230_rx_read_frame_complete;
	rc = spi_async(lp->spi, &lp->irq.msg);
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
	if (rc) {
		enable_irq(lp->spi->irq);
		ctx->trx.len = 2;
		at86rf230_async_error(lp, &lp->irq, rc);
		enable_irq(ctx->irq);
		at86rf230_async_error(lp, ctx, rc);
	}
	}
}
}


static void
static void
at86rf230_rx_trac_check(void *context)
at86rf230_rx_trac_check(void *context)
{
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;

	/* Possible check on trac status here. This could be useful to make
	/* Possible check on trac status here. This could be useful to make
	 * some stats why receive is failed. Not used at the moment, but it's
	 * some stats why receive is failed. Not used at the moment, but it's
	 * maybe timing relevant. Datasheet doesn't say anything about this.
	 * maybe timing relevant. Datasheet doesn't say anything about this.
	 * The programming guide say do it so.
	 * The programming guide say do it so.
	 */
	 */


	at86rf230_rx_read_frame(lp);
	at86rf230_rx_read_frame(context);
}
}


static void
static void
@@ -862,13 +905,13 @@ at86rf230_irq_status(void *context)
{
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;
	const u8 *buf = lp->irq.buf;
	const u8 *buf = ctx->buf;
	const u8 irq = buf[1];
	const u8 irq = buf[1];


	if (irq & IRQ_TRX_END) {
	if (irq & IRQ_TRX_END) {
		at86rf230_irq_trx_end(lp);
		at86rf230_irq_trx_end(lp);
	} else {
	} else {
		enable_irq(lp->spi->irq);
		enable_irq(ctx->irq);
		dev_err(&lp->spi->dev, "not supported irq %02x received\n",
		dev_err(&lp->spi->dev, "not supported irq %02x received\n",
			irq);
			irq);
	}
	}
@@ -884,7 +927,6 @@ static irqreturn_t at86rf230_isr(int irq, void *data)
	disable_irq_nosync(irq);
	disable_irq_nosync(irq);


	buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG;
	buf[0] = (RG_IRQ_STATUS & CMD_REG_MASK) | CMD_REG;
	ctx->trx.len = 2;
	ctx->msg.complete = at86rf230_irq_status;
	ctx->msg.complete = at86rf230_irq_status;
	rc = spi_async(lp->spi, &ctx->msg);
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc) {
	if (rc) {
@@ -919,7 +961,7 @@ at86rf230_write_frame(void *context)
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;
	struct at86rf230_local *lp = ctx->lp;
	struct sk_buff *skb = lp->tx_skb;
	struct sk_buff *skb = lp->tx_skb;
	u8 *buf = lp->tx.buf;
	u8 *buf = ctx->buf;
	int rc;
	int rc;


	spin_lock(&lp->lock);
	spin_lock(&lp->lock);
@@ -929,12 +971,14 @@ at86rf230_write_frame(void *context)
	buf[0] = CMD_FB | CMD_WRITE;
	buf[0] = CMD_FB | CMD_WRITE;
	buf[1] = skb->len + 2;
	buf[1] = skb->len + 2;
	memcpy(buf + 2, skb->data, skb->len);
	memcpy(buf + 2, skb->data, skb->len);
	lp->tx.trx.len = skb->len + 2;
	ctx->trx.len = skb->len + 2;
	lp->tx.msg.complete = at86rf230_write_frame_complete;
	ctx->msg.complete = at86rf230_write_frame_complete;
	rc = spi_async(lp->spi, &lp->tx.msg);
	rc = spi_async(lp->spi, &ctx->msg);
	if (rc)
	if (rc) {
		ctx->trx.len = 2;
		at86rf230_async_error(lp, ctx, rc);
		at86rf230_async_error(lp, ctx, rc);
	}
	}
}


static void
static void
at86rf230_xmit_tx_on(void *context)
at86rf230_xmit_tx_on(void *context)
@@ -946,24 +990,45 @@ at86rf230_xmit_tx_on(void *context)
				     at86rf230_write_frame, false);
				     at86rf230_write_frame, false);
}
}


static void
at86rf230_xmit_start(void *context)
{
	struct at86rf230_state_change *ctx = context;
	struct at86rf230_local *lp = ctx->lp;

	/* In ARET mode we need to go into STATE_TX_ARET_ON after we
	 * are in STATE_TX_ON. The pfad differs here, so we change
	 * the complete handler.
	 */
	if (lp->tx_aret)
		at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
					     at86rf230_xmit_tx_on, false);
	else
		at86rf230_async_state_change(lp, ctx, STATE_TX_ON,
					     at86rf230_write_frame, false);
}

static int
static int
at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
at86rf230_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
{
{
	struct at86rf230_local *lp = hw->priv;
	struct at86rf230_local *lp = hw->priv;
	struct at86rf230_state_change *ctx = &lp->tx;
	struct at86rf230_state_change *ctx = &lp->tx;


	void (*tx_complete)(void *context) = at86rf230_write_frame;

	lp->tx_skb = skb;
	lp->tx_skb = skb;
	lp->tx_retry = 0;


	/* In ARET mode we need to go into STATE_TX_ARET_ON after we
	/* After 5 minutes in PLL and the same frequency we run again the
	 * are in STATE_TX_ON. The pfad differs here, so we change
	 * calibration loops which is recommended by at86rf2xx datasheets.
	 * the complete handler.
	 *
	 * The calibration is initiate by a state change from TRX_OFF
	 * to TX_ON, the lp->cal_timeout should be reinit by state_delay
	 * function then to start in the next 5 minutes.
	 */
	 */
	if (lp->tx_aret)
	if (time_is_before_jiffies(lp->cal_timeout))
		tx_complete = at86rf230_xmit_tx_on;
		at86rf230_async_state_change(lp, ctx, STATE_TRX_OFF,

					     at86rf230_xmit_start, false);
	at86rf230_async_state_change(lp, ctx, STATE_TX_ON, tx_complete, false);
	else
		at86rf230_xmit_start(ctx);


	return 0;
	return 0;
}
}
@@ -979,6 +1044,9 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level)
static int
static int
at86rf230_start(struct ieee802154_hw *hw)
at86rf230_start(struct ieee802154_hw *hw)
{
{
	struct at86rf230_local *lp = hw->priv;

	lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
	return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON);
	return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON);
}
}


@@ -1059,6 +1127,8 @@ at86rf230_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
	/* Wait for PLL */
	/* Wait for PLL */
	usleep_range(lp->data->t_channel_switch,
	usleep_range(lp->data->t_channel_switch,
		     lp->data->t_channel_switch + 10);
		     lp->data->t_channel_switch + 10);

	lp->cal_timeout = jiffies + AT86RF2XX_CAL_LOOP_TIMEOUT;
	return rc;
	return rc;
}
}


@@ -1528,25 +1598,37 @@ static void
at86rf230_setup_spi_messages(struct at86rf230_local *lp)
at86rf230_setup_spi_messages(struct at86rf230_local *lp)
{
{
	lp->state.lp = lp;
	lp->state.lp = lp;
	lp->state.irq = lp->spi->irq;
	spi_message_init(&lp->state.msg);
	spi_message_init(&lp->state.msg);
	lp->state.msg.context = &lp->state;
	lp->state.msg.context = &lp->state;
	lp->state.trx.len = 2;
	lp->state.trx.tx_buf = lp->state.buf;
	lp->state.trx.tx_buf = lp->state.buf;
	lp->state.trx.rx_buf = lp->state.buf;
	lp->state.trx.rx_buf = lp->state.buf;
	spi_message_add_tail(&lp->state.trx, &lp->state.msg);
	spi_message_add_tail(&lp->state.trx, &lp->state.msg);
	hrtimer_init(&lp->state.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	lp->state.timer.function = at86rf230_async_state_timer;


	lp->irq.lp = lp;
	lp->irq.lp = lp;
	lp->irq.irq = lp->spi->irq;
	spi_message_init(&lp->irq.msg);
	spi_message_init(&lp->irq.msg);
	lp->irq.msg.context = &lp->irq;
	lp->irq.msg.context = &lp->irq;
	lp->irq.trx.len = 2;
	lp->irq.trx.tx_buf = lp->irq.buf;
	lp->irq.trx.tx_buf = lp->irq.buf;
	lp->irq.trx.rx_buf = lp->irq.buf;
	lp->irq.trx.rx_buf = lp->irq.buf;
	spi_message_add_tail(&lp->irq.trx, &lp->irq.msg);
	spi_message_add_tail(&lp->irq.trx, &lp->irq.msg);
	hrtimer_init(&lp->irq.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	lp->irq.timer.function = at86rf230_async_state_timer;


	lp->tx.lp = lp;
	lp->tx.lp = lp;
	lp->tx.irq = lp->spi->irq;
	spi_message_init(&lp->tx.msg);
	spi_message_init(&lp->tx.msg);
	lp->tx.msg.context = &lp->tx;
	lp->tx.msg.context = &lp->tx;
	lp->tx.trx.len = 2;
	lp->tx.trx.tx_buf = lp->tx.buf;
	lp->tx.trx.tx_buf = lp->tx.buf;
	lp->tx.trx.rx_buf = lp->tx.buf;
	lp->tx.trx.rx_buf = lp->tx.buf;
	spi_message_add_tail(&lp->tx.trx, &lp->tx.msg);
	spi_message_add_tail(&lp->tx.trx, &lp->tx.msg);
	hrtimer_init(&lp->tx.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	lp->tx.timer.function = at86rf230_async_state_timer;
}
}


static int at86rf230_probe(struct spi_device *spi)
static int at86rf230_probe(struct spi_device *spi)
@@ -1555,7 +1637,7 @@ static int at86rf230_probe(struct spi_device *spi)
	struct at86rf230_local *lp;
	struct at86rf230_local *lp;
	unsigned int status;
	unsigned int status;
	int rc, irq_type, rstn, slp_tr;
	int rc, irq_type, rstn, slp_tr;
	u8 xtal_trim;
	u8 xtal_trim = 0;


	if (!spi->irq) {
	if (!spi->irq) {
		dev_err(&spi->dev, "no IRQ specified\n");
		dev_err(&spi->dev, "no IRQ specified\n");
+2 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@
#define IEEE802154_MTU			127
#define IEEE802154_MTU			127
#define IEEE802154_ACK_PSDU_LEN		5
#define IEEE802154_ACK_PSDU_LEN		5
#define IEEE802154_MIN_PSDU_LEN		9
#define IEEE802154_MIN_PSDU_LEN		9
#define IEEE802154_FCS_LEN		2


#define IEEE802154_PAN_ID_BROADCAST	0xffff
#define IEEE802154_PAN_ID_BROADCAST	0xffff
#define IEEE802154_ADDR_SHORT_BROADCAST	0xffff
#define IEEE802154_ADDR_SHORT_BROADCAST	0xffff
@@ -39,6 +40,7 @@


#define IEEE802154_LIFS_PERIOD		40
#define IEEE802154_LIFS_PERIOD		40
#define IEEE802154_SIFS_PERIOD		12
#define IEEE802154_SIFS_PERIOD		12
#define IEEE802154_MAX_SIFS_FRAME_SIZE	18


#define IEEE802154_MAX_CHANNEL		26
#define IEEE802154_MAX_CHANNEL		26
#define IEEE802154_MAX_PAGE		31
#define IEEE802154_MAX_PAGE		31
+3 −0
Original line number Original line Diff line number Diff line
@@ -354,6 +354,9 @@ void l2cap_exit(void);
int sco_init(void);
int sco_init(void);
void sco_exit(void);
void sco_exit(void);


int mgmt_init(void);
void mgmt_exit(void);

void bt_sock_reclassify_lock(struct sock *sk, int proto);
void bt_sock_reclassify_lock(struct sock *sk, int proto);


#endif /* __BLUETOOTH_H */
#endif /* __BLUETOOTH_H */
+7 −15
Original line number Original line Diff line number Diff line
@@ -179,15 +179,6 @@ enum {
	HCI_RESET,
	HCI_RESET,
};
};


/* BR/EDR and/or LE controller flags: the flags defined here should represent
 * states configured via debugfs for debugging and testing purposes only.
 */
enum {
	HCI_DUT_MODE,
	HCI_FORCE_BREDR_SMP,
	HCI_FORCE_STATIC_ADDR,
};

/*
/*
 * BR/EDR and/or LE controller flags: the flags defined here should represent
 * BR/EDR and/or LE controller flags: the flags defined here should represent
 * states from the controller.
 * states from the controller.
@@ -217,6 +208,7 @@ enum {
	HCI_HS_ENABLED,
	HCI_HS_ENABLED,
	HCI_LE_ENABLED,
	HCI_LE_ENABLED,
	HCI_ADVERTISING,
	HCI_ADVERTISING,
	HCI_ADVERTISING_CONNECTABLE,
	HCI_CONNECTABLE,
	HCI_CONNECTABLE,
	HCI_DISCOVERABLE,
	HCI_DISCOVERABLE,
	HCI_LIMITED_DISCOVERABLE,
	HCI_LIMITED_DISCOVERABLE,
@@ -225,13 +217,13 @@ enum {
	HCI_FAST_CONNECTABLE,
	HCI_FAST_CONNECTABLE,
	HCI_BREDR_ENABLED,
	HCI_BREDR_ENABLED,
	HCI_LE_SCAN_INTERRUPTED,
	HCI_LE_SCAN_INTERRUPTED,
};


/* A mask for the flags that are supposed to remain when a reset happens
	HCI_DUT_MODE,
 * or the HCI device is closed.
	HCI_FORCE_BREDR_SMP,
 */
	HCI_FORCE_STATIC_ADDR,
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \

			      BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV))
	__HCI_NUM_FLAGS,
};


/* HCI timeouts */
/* HCI timeouts */
#define HCI_DISCONN_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
#define HCI_DISCONN_TIMEOUT	msecs_to_jiffies(2000)	/* 2 seconds */
Loading