From bdc78737278ee77fdcbccaee5b6f7eda4e0e7602 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 29 May 2015 10:51:25 +0200 Subject: ieee802154/atusb: Add function for partial register writes With this function we can set individual bits in the registers if needed. With the old SR_VALUE macro we could only set one bit in the register which was ok for some scenarios but not for all. With this subreg write function we can now set more bits defined by the mask while not touching the rest. We start using it for the current SR_VALUE use case and will use it more in upcoming patches. Signed-off-by: Stefan Schmidt Reviewed-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/atusb.c | 45 +++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 5b6bb9adf9ae..95d42205fd53 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -58,17 +58,6 @@ struct atusb { uint8_t tx_ack_seq; /* current TX ACK sequence number */ }; -/* at86rf230.h defines values as tuples. We use the more - * traditional style of having registers and or-able values. SR_REG extracts - * the register number. SR_VALUE uses the shift to prepare a value accordingly. - */ - -#define __SR_REG(reg, mask, shift) (reg) -#define SR_REG(sr) __SR_REG(sr) - -#define __SR_VALUE(reg, mask, shift, val) ((val) << (shift)) -#define SR_VALUE(sr, val) __SR_VALUE(sr, (val)) - /* ----- USB commands without data ----------------------------------------- */ /* To reduce the number of error checks in the code, we record the first error @@ -130,6 +119,30 @@ static int atusb_read_reg(struct atusb *atusb, uint8_t reg) return ret >= 0 ? value : ret; } +static int atusb_write_subreg(struct atusb *atusb, uint8_t reg, uint8_t mask, + uint8_t shift, uint8_t value) +{ + struct usb_device *usb_dev = atusb->usb_dev; + uint8_t orig, tmp; + int ret = 0; + + dev_dbg(&usb_dev->dev, "atusb_write_subreg: 0x%02x <- 0x%02x\n", + reg, value); + + orig = atusb_read_reg(atusb, reg); + + /* Write the value only into that part of the register which is allowed + * by the mask. All other bits stay as before. + */ + tmp = orig & ~mask; + tmp |= (value << shift) & mask; + + if (tmp != orig) + ret = atusb_write_reg(atusb, reg, tmp); + + return ret; +} + static int atusb_get_and_clear_error(struct atusb *atusb) { int err = atusb->err; @@ -376,7 +389,6 @@ static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw, { struct atusb *atusb = hw->priv; struct device *dev = &atusb->usb_dev->dev; - uint8_t reg; if (changed & IEEE802154_AFILT_SADDR_CHANGED) { u16 addr = le16_to_cpu(filt->short_addr); @@ -406,12 +418,10 @@ static int atusb_set_hw_addr_filt(struct ieee802154_hw *hw, if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(dev, "atusb_set_hw_addr_filt called for panc change\n"); - reg = atusb_read_reg(atusb, SR_REG(SR_AACK_I_AM_COORD)); if (filt->pan_coord) - reg |= SR_VALUE(SR_AACK_I_AM_COORD, 1); + atusb_write_subreg(atusb, SR_AACK_I_AM_COORD, 1); else - reg &= ~SR_VALUE(SR_AACK_I_AM_COORD, 1); - atusb_write_reg(atusb, SR_REG(SR_AACK_I_AM_COORD), reg); + atusb_write_subreg(atusb, SR_AACK_I_AM_COORD, 0); } return atusb_get_and_clear_error(atusb); @@ -622,8 +632,7 @@ static int atusb_probe(struct usb_interface *interface, * http://www.jennic.com/download_file.php?supportFile=JN-AN-1035%20Calculating%20802-15-4%20Data%20Rates-1v0.pdf */ - atusb_write_reg(atusb, - SR_REG(SR_RX_SAFE_MODE), SR_VALUE(SR_RX_SAFE_MODE, 1)); + atusb_write_subreg(atusb, SR_RX_SAFE_MODE, 1); #endif atusb_write_reg(atusb, RG_IRQ_MASK, 0xff); -- cgit v1.2.3 From 8702cb0f21905a2a96f61c5106a2c42d41c17999 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 29 May 2015 10:51:26 +0200 Subject: ieee802154/atusb: Add .set_txpower operation to the driver Atusb uses the at86rf231 transceiver so we can use the same calculation for txpower settings for it. Signed-off-by: Stefan Schmidt Reviewed-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/atusb.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 95d42205fd53..9805ebeccd75 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -453,6 +453,26 @@ static void atusb_stop(struct ieee802154_hw *hw) atusb_get_and_clear_error(atusb); } +#define ATUSB_MAX_TX_POWERS 0xF +static const s32 atusb_powers[ATUSB_MAX_TX_POWERS + 1] = { + 300, 280, 230, 180, 130, 70, 0, -100, -200, -300, -400, -500, -700, + -900, -1200, -1700, +}; + +static int +atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm) +{ + struct atusb *atusb = hw->priv; + u32 i; + + for (i = 0; i < hw->phy->supported.tx_powers_size; i++) { + if (hw->phy->supported.tx_powers[i] == mbm) + return atusb_write_subreg(atusb, SR_TX_PWR_23X, i); + } + + return -EINVAL; +} + static struct ieee802154_ops atusb_ops = { .owner = THIS_MODULE, .xmit_async = atusb_xmit, @@ -461,6 +481,7 @@ static struct ieee802154_ops atusb_ops = { .start = atusb_start, .stop = atusb_stop, .set_hw_addr_filt = atusb_set_hw_addr_filt, + .set_txpower = atusb_set_txpower, }; /* ----- Firmware and chip version information ----------------------------- */ @@ -581,9 +602,14 @@ static int atusb_probe(struct usb_interface *interface, hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | IEEE802154_HW_AACK; + hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; + hw->phy->current_page = 0; hw->phy->current_channel = 11; /* reset default */ hw->phy->supported.channels[0] = 0x7FFF800; + hw->phy->supported.tx_powers = atusb_powers; + hw->phy->supported.tx_powers_size = ARRAY_SIZE(atusb_powers); + hw->phy->transmit_power = hw->phy->supported.tx_powers[0]; ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); atusb_command(atusb, ATUSB_RF_RESET, 0); -- cgit v1.2.3 From c61c9bd81bea4e2c86058123e8d221a40b9c58a3 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Fri, 29 May 2015 10:51:27 +0200 Subject: ieee802154/atusb: Add .set_promiscuous_mode driver operation Allow monitor mode operation with disabled AACK in hardware. Signed-off-by: Stefan Schmidt Reviewed-by: Varka Bhadram Acked-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/atusb.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 9805ebeccd75..3d25678dfd95 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -473,6 +473,33 @@ atusb_set_txpower(struct ieee802154_hw *hw, s32 mbm) return -EINVAL; } +static int +atusb_set_promiscuous_mode(struct ieee802154_hw *hw, const bool on) +{ + struct atusb *atusb = hw->priv; + int ret; + + if (on) { + ret = atusb_write_subreg(atusb, SR_AACK_DIS_ACK, 1); + if (ret < 0) + return ret; + + ret = atusb_write_subreg(atusb, SR_AACK_PROM_MODE, 1); + if (ret < 0) + return ret; + } else { + ret = atusb_write_subreg(atusb, SR_AACK_PROM_MODE, 0); + if (ret < 0) + return ret; + + ret = atusb_write_subreg(atusb, SR_AACK_DIS_ACK, 0); + if (ret < 0) + return ret; + } + + return 0; +} + static struct ieee802154_ops atusb_ops = { .owner = THIS_MODULE, .xmit_async = atusb_xmit, @@ -482,6 +509,7 @@ static struct ieee802154_ops atusb_ops = { .stop = atusb_stop, .set_hw_addr_filt = atusb_set_hw_addr_filt, .set_txpower = atusb_set_txpower, + .set_promiscuous_mode = atusb_set_promiscuous_mode, }; /* ----- Firmware and chip version information ----------------------------- */ @@ -600,7 +628,7 @@ static int atusb_probe(struct usb_interface *interface, hw->parent = &usb_dev->dev; hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | - IEEE802154_HW_AACK; + IEEE802154_HW_AACK | IEEE802154_HW_PROMISCUOUS; hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; -- cgit v1.2.3 From aad1b0b5d3e0e4cdadd695b7188873ba614ca4ef Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 29 May 2015 10:56:54 +0530 Subject: cc2520: fix in default tx power setting Initially we dont have the tx power settings from the user-space. Now we have the support for seeting the tx power level. So lets use the default tx power setting for the radio. Signed-off-by: Varka Bhadram Cc: Brad Campbell Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 84b28a05c5a1..ea280d437ca1 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -782,10 +782,6 @@ static int cc2520_hw_init(struct cc2520_private *priv) * http://www.ti.com/lit/an/swra229a/swra229a.pdf */ if (pdata.amplified) { - ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF9); - if (ret) - goto err_ret; - ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16); if (ret) goto err_ret; @@ -806,10 +802,6 @@ static int cc2520_hw_init(struct cc2520_private *priv) if (ret) goto err_ret; } else { - ret = cc2520_write_register(priv, CC2520_TXPOWER, 0xF7); - if (ret) - goto err_ret; - ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x11); if (ret) goto err_ret; -- cgit v1.2.3 From 1a1bc59c5f7657387d1a4b45d63248fed55ab88c Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 29 May 2015 10:56:55 +0530 Subject: cc2520: fix CC2591 handling This patch changes tha way of handling of cc2591-cc2520 combination by moving amplified variable from platform data to private data. This will be useful in other sections like tx power support. Signed-off-by: Varka Bhadram Cc: Brad Campbell Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index ea280d437ca1..0d9353756598 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -196,6 +196,7 @@ struct cc2520_private { u8 *buf; /* SPI TX/Rx data buffer */ struct mutex buffer_mutex; /* SPI buffer mutex */ bool is_tx; /* Flag for sync b/w Tx and Rx */ + bool amplified; /* Flag for CC2591 */ int fifo_pin; /* FIFO GPIO pin number */ struct work_struct fifop_irqwork;/* Workqueue for FIFOP */ spinlock_t lock; /* Lock for is_tx*/ @@ -738,7 +739,9 @@ static int cc2520_get_platform_data(struct spi_device *spi, pdata->vreg = of_get_named_gpio(np, "vreg-gpio", 0); pdata->reset = of_get_named_gpio(np, "reset-gpio", 0); - pdata->amplified = of_property_read_bool(np, "amplified"); + /* CC2591 front end for CC2520 */ + if (of_property_read_bool(np, "amplified")) + priv->amplified = true; return 0; } @@ -781,7 +784,7 @@ static int cc2520_hw_init(struct cc2520_private *priv) * amplifier. See section 8 page 17 of TI application note AN065. * http://www.ti.com/lit/an/swra229a/swra229a.pdf */ - if (pdata.amplified) { + if (priv->amplified) { ret = cc2520_write_register(priv, CC2520_AGCCTRL1, 0x16); if (ret) goto err_ret; @@ -896,6 +899,9 @@ static int cc2520_probe(struct spi_device *spi) spin_lock_init(&priv->lock); init_completion(&priv->tx_complete); + /* Assumption that CC2591 is not connected */ + priv->amplified = false; + /* Request all the gpio's */ if (!gpio_is_valid(pdata.fifo)) { dev_err(&spi->dev, "fifo gpio is not valid\n"); -- cgit v1.2.3 From e10c1674e31558807fcccfbf3dbebbc1cad9099c Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 29 May 2015 10:56:56 +0530 Subject: cc2520: add set transmit power setting support This patch adds support for seeting tx power values for cc2520 and also for the combination of CC2520-CC2591. Signed-off-by: Varka Bhadram Cc: Brad Campbell Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 102 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 0d9353756598..36a4f312cc7c 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -629,6 +629,97 @@ cc2520_filter(struct ieee802154_hw *hw, return 0; } +static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm) +{ + u8 power; + + switch (mbm) { + case 500: + power = 0xF7; + break; + case 300: + power = 0xF2; + break; + case 200: + power = 0xAB; + break; + case 100: + power = 0x13; + break; + case 0: + power = 0x32; + break; + case -200: + power = 0x81; + break; + case -400: + power = 0x88; + break; + case -700: + power = 0x2C; + break; + case -1800: + power = 0x03; + break; + default: + return -EINVAL; + } + + return cc2520_write_register(priv, CC2520_TXPOWER, power); +} + +static inline int cc2520_cc2591_set_tx_power(struct cc2520_private *priv, + s32 mbm) +{ + u8 power; + + switch (mbm) { + case 1700: + power = 0xF9; + break; + case 1600: + power = 0xF0; + break; + case 1400: + power = 0xA0; + break; + case 1100: + power = 0x2C; + break; + case -100: + power = 0x03; + break; + case -800: + power = 0x01; + break; + default: + return -EINVAL; + } + + return cc2520_write_register(priv, CC2520_TXPOWER, power); +} + +#define CC2520_MAX_TX_POWERS 0x8 +static const s32 cc2520_powers[CC2520_MAX_TX_POWERS + 1] = { + 500, 300, 200, 100, 0, -200, -400, -700, -1800, +}; + +#define CC2520_CC2591_MAX_TX_POWERS 0x5 +static const s32 cc2520_cc2591_powers[CC2520_CC2591_MAX_TX_POWERS + 1] = { + 1700, 1600, 1400, 1100, -100, -800, +}; + +static int +cc2520_set_txpower(struct ieee802154_hw *hw, s32 mbm) +{ + struct cc2520_private *priv = hw->priv; + + if (!priv->amplified) + return cc2520_set_tx_power(priv, mbm); + + return cc2520_cc2591_set_tx_power(priv, mbm); +} + static const struct ieee802154_ops cc2520_ops = { .owner = THIS_MODULE, .start = cc2520_start, @@ -637,6 +728,7 @@ static const struct ieee802154_ops cc2520_ops = { .ed = cc2520_ed, .set_channel = cc2520_set_channel, .set_hw_addr_filt = cc2520_filter, + .set_txpower = cc2520_set_txpower, }; static int cc2520_register(struct cc2520_private *priv) @@ -658,6 +750,16 @@ static int cc2520_register(struct cc2520_private *priv) priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | IEEE802154_HW_AFILT; + priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; + + if (!priv->amplified) { + priv->hw->phy->supported.tx_powers = cc2520_powers; + priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers); + } else { + priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers; + priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers); + } + dev_vdbg(&priv->spi->dev, "registered cc2520\n"); ret = ieee802154_register_hw(priv->hw); if (ret) -- cgit v1.2.3 From 322fe2d1beb7b381640999b48a7fb136e0870bb3 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 29 May 2015 10:56:57 +0530 Subject: cc2520: update initial transmit power value CC2520 has the default 0dBm transmit power level on reset. This patch update initial value of transmit power with 0dBm value. Signed-off-by: Varka Bhadram Cc: Brad Campbell Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 36a4f312cc7c..2384c286163f 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -755,9 +755,11 @@ static int cc2520_register(struct cc2520_private *priv) if (!priv->amplified) { priv->hw->phy->supported.tx_powers = cc2520_powers; priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_powers); + priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[4]; } else { priv->hw->phy->supported.tx_powers = cc2520_cc2591_powers; priv->hw->phy->supported.tx_powers_size = ARRAY_SIZE(cc2520_cc2591_powers); + priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0]; } dev_vdbg(&priv->spi->dev, "registered cc2520\n"); -- cgit v1.2.3 From d6d244d4df91ee4b468233050542c7482d705e69 Mon Sep 17 00:00:00 2001 From: Varka Bhadram Date: Fri, 29 May 2015 10:56:58 +0530 Subject: cc2520: update current channel This patch updates the current channel to 11. This is the default value on reset. Signed-off-by: Varka Bhadram Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 2384c286163f..8141353221a1 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -762,6 +762,8 @@ static int cc2520_register(struct cc2520_private *priv) priv->hw->phy->transmit_power = priv->hw->phy->supported.tx_powers[0]; } + priv->hw->phy->current_channel = 11; + dev_vdbg(&priv->spi->dev, "registered cc2520\n"); ret = ieee802154_register_hw(priv->hw); if (ret) -- cgit v1.2.3 From 4eeab599e1277a8a28b6b8740a29bf7e7a73f829 Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Tue, 2 Jun 2015 10:50:15 +0000 Subject: Bluetooth: vhci: Clean up coding style fix Fix spaces required around that '=' reported by checkpatch. Signed-off-by: Prasanna Karthik Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci_vhci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 6653473f2757..78653db2ef2b 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c @@ -366,7 +366,7 @@ static const struct file_operations vhci_fops = { .llseek = no_llseek, }; -static struct miscdevice vhci_miscdev= { +static struct miscdevice vhci_miscdev = { .name = "vhci", .fops = &vhci_fops, .minor = VHCI_MINOR, -- cgit v1.2.3 From 18aeb4445aa00f6f402ba3a92a2e9ff3d13882b4 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 28 May 2015 11:25:01 +0200 Subject: Bluetooth: btbcm: Move request/release_firmware() Move request/release_firmware() out of btbcm_patchram(). This allows a better error management, if request_firmware() returns an error then the controller will be used without firmware loading and 0 is returned. This will imply to change btbcm_patchram() to accept a firmware instead of firmware name. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 26 ++++++++++++-------------- drivers/bluetooth/btbcm.h | 4 ++-- drivers/bluetooth/hci_bcm.c | 1 + drivers/bluetooth/hci_ldisc.c | 1 + 4 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 728fce38a5a2..c7aec9776620 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -89,21 +89,14 @@ int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) } EXPORT_SYMBOL_GPL(btbcm_set_bdaddr); -int btbcm_patchram(struct hci_dev *hdev, const char *firmware) +int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) { const struct hci_command_hdr *cmd; - const struct firmware *fw; const u8 *fw_ptr; size_t fw_size; struct sk_buff *skb; u16 opcode; - int err; - - err = request_firmware(&fw, firmware, &hdev->dev); - if (err < 0) { - BT_INFO("%s: BCM: Patch %s not found", hdev->name, firmware); - return err; - } + int err = 0; /* Start Download */ skb = __hci_cmd_sync(hdev, 0xfc2e, 0, NULL, HCI_INIT_TIMEOUT); @@ -129,8 +122,7 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware) fw_size -= sizeof(*cmd); if (fw_size < cmd->plen) { - BT_ERR("%s: BCM: Patch %s is corrupted", hdev->name, - firmware); + BT_ERR("%s: BCM: Patch is corrupted", hdev->name); err = -EINVAL; goto done; } @@ -156,7 +148,6 @@ int btbcm_patchram(struct hci_dev *hdev, const char *firmware) msleep(250); done: - release_firmware(fw); return err; } EXPORT_SYMBOL(btbcm_patchram); @@ -265,6 +256,7 @@ static const struct { int btbcm_setup_patchram(struct hci_dev *hdev) { char fw_name[64]; + const struct firmware *fw; u16 subver, rev, pid, vid; const char *hw_name = NULL; struct sk_buff *skb; @@ -335,9 +327,15 @@ int btbcm_setup_patchram(struct hci_dev *hdev) hw_name ? : "BCM", (subver & 0x7000) >> 13, (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); - err = btbcm_patchram(hdev, fw_name); - if (err == -ENOENT) + err = request_firmware(&fw, fw_name, &hdev->dev); + if (err < 0) { + BT_INFO("%s: BCM: Patch %s not found", hdev->name, fw_name); return 0; + } + + btbcm_patchram(hdev, fw); + + release_firmware(fw); /* Reset */ err = btbcm_reset(hdev); diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index eb6ab5f9483d..42f26a6c7f81 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -25,7 +25,7 @@ int btbcm_check_bdaddr(struct hci_dev *hdev); int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr); -int btbcm_patchram(struct hci_dev *hdev, const char *firmware); +int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw); int btbcm_setup_patchram(struct hci_dev *hdev); int btbcm_setup_apple(struct hci_dev *hdev); @@ -42,7 +42,7 @@ static inline int btbcm_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr) return -EOPNOTSUPP; } -static inline int btbcm_patchram(struct hci_dev *hdev, const char *firmware) +static inline int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw) { return -EOPNOTSUPP; } diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 1ec0b4a5ffa6..8653d125e107 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 5c9a73f02664..114015d9eef4 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From a8f3b9418ad2dd8f3efee0c08cdd61ac3763e739 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 28 May 2015 11:25:02 +0200 Subject: Bluetooth: btbcm: Add BCM4324B3 UART device Add "waiting for configuration" address. Add lmp_subver and firmware name for BCM4324B3 controller. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index c7aec9776620..14e4647686bd 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -33,6 +33,7 @@ #define VERSION "0.1" #define BDADDR_BCM20702A0 (&(bdaddr_t) {{0x00, 0xa0, 0x02, 0x70, 0x20, 0x00}}) +#define BDADDR_BCM4324B3 (&(bdaddr_t) {{0x00, 0x00, 0x00, 0xb3, 0x24, 0x43}}) int btbcm_check_bdaddr(struct hci_dev *hdev) { @@ -56,10 +57,18 @@ int btbcm_check_bdaddr(struct hci_dev *hdev) bda = (struct hci_rp_read_bd_addr *)skb->data; - /* The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller + /* Check if the address indicates a controller with either an + * invalid or default address. In both cases the device needs + * to be marked as not having a valid address. + * + * The address 00:20:70:02:A0:00 indicates a BCM20702A0 controller * with no configured address. + * + * The address 43:24:B3:00:00:00 indicates a BCM4324B3 controller + * with waiting for configuration state. */ - if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0)) { + if (!bacmp(&bda->bdaddr, BDADDR_BCM20702A0) || + !bacmp(&bda->bdaddr, BDADDR_BCM4324B3)) { BT_INFO("%s: BCM: Using default device address (%pMR)", hdev->name, &bda->bdaddr); set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); @@ -233,6 +242,7 @@ static const struct { const char *name; } bcm_uart_subver_table[] = { { 0x410e, "BCM43341B0" }, /* 002.001.014 */ + { 0x4406, "BCM4324B3" }, /* 002.004.006 */ { } }; @@ -288,6 +298,7 @@ int btbcm_setup_patchram(struct hci_dev *hdev) switch ((rev & 0xf000) >> 12) { case 0: + case 3: for (i = 0; bcm_uart_subver_table[i].name; i++) { if (subver == bcm_uart_subver_table[i].subver) { hw_name = bcm_uart_subver_table[i].name; -- cgit v1.2.3 From 7721383f4199bb704c664f009423bc228bbac52e Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 28 May 2015 11:25:03 +0200 Subject: Bluetooth: hci_uart: Support operational speed during setup Add initial and operational speeds. Change to operational speed as soon as possible. If controller set_baudrate() fails, continue at initial speed. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ldisc.c | 26 ++++++++++++++++++++++++++ drivers/bluetooth/hci_uart.h | 4 ++++ 2 files changed, 30 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 114015d9eef4..ac87346ce9d7 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -266,11 +266,37 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed) +{ + struct tty_struct *tty = hu->tty; + struct ktermios ktermios; + + ktermios = tty->termios; + ktermios.c_cflag &= ~CBAUD; + ktermios.c_cflag |= BOTHER; + tty_termios_encode_baud_rate(&ktermios, speed, speed); + + /* tty_set_termios() return not checked as it is always 0 */ + tty_set_termios(tty, &ktermios); + + BT_DBG("%s: New tty speed: %d", hu->hdev->name, tty->termios.c_ispeed); +} + static int hci_uart_setup(struct hci_dev *hdev) { struct hci_uart *hu = hci_get_drvdata(hdev); struct hci_rp_read_local_version *ver; struct sk_buff *skb; + int err; + + if (hu->proto->init_speed) + hci_uart_set_baudrate(hu, hu->proto->init_speed); + + if (hu->proto->set_baudrate && hu->proto->oper_speed) { + err = hu->proto->set_baudrate(hu, hu->proto->oper_speed); + if (!err) + hci_uart_set_baudrate(hu, hu->proto->oper_speed); + } if (hu->proto->setup) return hu->proto->setup(hu); diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 72120a5ba13c..e9f970c25304 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -58,10 +58,13 @@ struct hci_uart; struct hci_uart_proto { unsigned int id; const char *name; + unsigned int init_speed; + unsigned int oper_speed; int (*open)(struct hci_uart *hu); int (*close)(struct hci_uart *hu); int (*flush)(struct hci_uart *hu); int (*setup)(struct hci_uart *hu); + int (*set_baudrate)(struct hci_uart *hu, unsigned int speed); int (*recv)(struct hci_uart *hu, const void *data, int len); int (*enqueue)(struct hci_uart *hu, struct sk_buff *skb); struct sk_buff *(*dequeue)(struct hci_uart *hu); @@ -96,6 +99,7 @@ int hci_uart_register_proto(const struct hci_uart_proto *p); int hci_uart_unregister_proto(const struct hci_uart_proto *p); int hci_uart_tx_wakeup(struct hci_uart *hu); int hci_uart_init_ready(struct hci_uart *hu); +void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed); #ifdef CONFIG_BT_HCIUART_H4 int h4_init(void); -- cgit v1.2.3 From 75e167e6f0ddcf65567c0a604e4827f0a914a4c1 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 28 May 2015 11:25:04 +0200 Subject: Bluetooth: btbcm: Add helper functions for UART setup Firmware loading may reset the controller UART speed and needs to set host UART speed back to init speed. UART drivers setup is split in 3 parts: - btbcm_initialize() resets the controller and returns the firmware name based on controller revision and sub_version. - btbtcm_patchram() (already existing and public), which takes the firmware name as parameter, requests the firmware and loads it to the controller. - btbcm_finalize() which resets the controller, reads local version and checks if the controller address is a default one or not. Remove firmware name retrieval for UART controllers from btbcm_setup_patchram(). Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/bluetooth/btbcm.h | 14 ++++++++ 2 files changed, 103 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 14e4647686bd..8e2f6b6251c4 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -246,6 +246,95 @@ static const struct { { } }; +int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len) +{ + u16 subver, rev; + const char *hw_name = NULL; + struct sk_buff *skb; + struct hci_rp_read_local_version *ver; + int i, err; + + /* Reset */ + err = btbcm_reset(hdev); + if (err) + return err; + + /* Read Local Version Info */ + skb = btbcm_read_local_version(hdev); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + ver = (struct hci_rp_read_local_version *)skb->data; + rev = le16_to_cpu(ver->hci_rev); + subver = le16_to_cpu(ver->lmp_subver); + kfree_skb(skb); + + /* Read Verbose Config Version Info */ + skb = btbcm_read_verbose_config(hdev); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + BT_INFO("%s: BCM: chip id %u", hdev->name, skb->data[1]); + kfree_skb(skb); + + switch ((rev & 0xf000) >> 12) { + case 0: + case 3: + for (i = 0; bcm_uart_subver_table[i].name; i++) { + if (subver == bcm_uart_subver_table[i].subver) { + hw_name = bcm_uart_subver_table[i].name; + break; + } + } + + snprintf(fw_name, len, "brcm/%s.hcd", hw_name ? : "BCM"); + break; + default: + return 0; + } + + BT_INFO("%s: %s (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, + hw_name ? : "BCM", (subver & 0x7000) >> 13, + (subver & 0x1f00) >> 8, (subver & 0x00ff), rev & 0x0fff); + + return 0; +} +EXPORT_SYMBOL_GPL(btbcm_initialize); + +int btbcm_finalize(struct hci_dev *hdev) +{ + struct sk_buff *skb; + struct hci_rp_read_local_version *ver; + u16 subver, rev; + int err; + + /* Reset */ + err = btbcm_reset(hdev); + if (err) + return err; + + /* Read Local Version Info */ + skb = btbcm_read_local_version(hdev); + if (IS_ERR(skb)) + return PTR_ERR(skb); + + ver = (struct hci_rp_read_local_version *)skb->data; + rev = le16_to_cpu(ver->hci_rev); + subver = le16_to_cpu(ver->lmp_subver); + kfree_skb(skb); + + BT_INFO("%s: BCM (%3.3u.%3.3u.%3.3u) build %4.4u", hdev->name, + (subver & 0x7000) >> 13, (subver & 0x1f00) >> 8, + (subver & 0x00ff), rev & 0x0fff); + + btbcm_check_bdaddr(hdev); + + set_bit(HCI_QUIRK_STRICT_DUPLICATE_FILTER, &hdev->quirks); + + return 0; +} +EXPORT_SYMBOL_GPL(btbcm_finalize); + static const struct { u16 subver; const char *name; diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index 42f26a6c7f81..f405f8424399 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -30,6 +30,9 @@ int btbcm_patchram(struct hci_dev *hdev, const struct firmware *fw); int btbcm_setup_patchram(struct hci_dev *hdev); int btbcm_setup_apple(struct hci_dev *hdev); +int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len); +int btbcm_finalize(struct hci_dev *hdev); + #else static inline int btbcm_check_bdaddr(struct hci_dev *hdev) @@ -57,4 +60,15 @@ static inline int btbcm_setup_apple(struct hci_dev *hdev) return 0; } +static inline int btbcm_initialize(struct hci_dev *hdev, char *fw_name, + size_t len) +{ + return 0; +} + +static inline int btbcm_finalize(struct hci_dev *hdev) +{ + return 0; +} + #endif -- cgit v1.2.3 From 6be09b48ae8bcce8426877b5f89e6218ffb657b0 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 28 May 2015 11:25:05 +0200 Subject: Bluetooth: hci_uart: Update Broadcom UART setup Use btbcm helpers to perform controller setup. Perform host UART reset to init speed between btbcm_patchram() and btbcm_finalize(). This may be need because firmware loading may have reseted controller UART to init speed. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 8653d125e107..070452256816 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -80,11 +80,39 @@ static int bcm_flush(struct hci_uart *hu) static int bcm_setup(struct hci_uart *hu) { + char fw_name[64]; + const struct firmware *fw; + int err; + BT_DBG("hu %p", hu); hu->hdev->set_bdaddr = btbcm_set_bdaddr; - return btbcm_setup_patchram(hu->hdev); + err = btbcm_initialize(hu->hdev, fw_name, sizeof(fw_name)); + if (err) + return err; + + err = request_firmware(&fw, fw_name, &hu->hdev->dev); + if (err < 0) { + BT_INFO("%s: BCM: Patch %s not found", hu->hdev->name, fw_name); + return 0; + } + + err = btbcm_patchram(hu->hdev, fw); + if (err) { + BT_INFO("%s: BCM: Patch failed (%d)", hu->hdev->name, err); + goto finalize; + } + + if (hu->proto->init_speed) + hci_uart_set_baudrate(hu, hu->proto->init_speed); + +finalize: + release_firmware(fw); + + err = btbcm_finalize(hu->hdev); + + return err; } static const struct h4_recv_pkt bcm_recv_pkts[] = { -- cgit v1.2.3 From ed65963ba0a2bdc330b1d7183f930d1c6a0a6685 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 6 Jun 2015 17:30:46 +0200 Subject: mac802154: remove unneeded vif struct This patch removes the virtual interface structure from sub if data struct, because it isn't used anywhere. This structure could be useful for give per interface information at softmac driver layer. Nevertheless there exist no use case currently and it contains the interface type information currently. This information is also stored inside wpan dev which is now used to check on the wpan dev interface type. Signed-off-by: Alexander Aring Reviewed-by: Varka Bhadram Acked-by: Varka Bhadram Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 1 - drivers/net/ieee802154/cc2520.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 2f25a5ed8247..6e20e9c94b3c 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1602,7 +1602,6 @@ static int at86rf230_probe(struct spi_device *spi) lp->spi = spi; lp->slp_tr = slp_tr; hw->parent = &spi->dev; - hw->vif_data_size = sizeof(*lp); ieee802154_random_extended_addr(&hw->phy->perm_extended_addr); lp->regmap = devm_regmap_init_spi(spi, &at86rf230_regmap_spi_config); diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 8141353221a1..a8bafd6bd5e4 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -742,7 +742,6 @@ static int cc2520_register(struct cc2520_private *priv) priv->hw->priv = priv; priv->hw->parent = &priv->spi->dev; priv->hw->extra_tx_headroom = 0; - priv->hw->vif_data_size = sizeof(*priv); ieee802154_random_extended_addr(&priv->hw->phy->perm_extended_addr); /* We do support only 2.4 Ghz */ -- cgit v1.2.3 From f265be3d124a5b62e5a339685b6cfaa0292f1250 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 6 Jun 2015 17:30:48 +0200 Subject: mac802154: remove aack hw flag This patch removes the hardware auto acknowdledge flag which indicates that the transceiver supports this handling. This flag is never evaluated inside mac802154 and all transceivers should support this handling by default per hardware. Suggested-by: Lennert Buytenhek Cc: Alan Ott Signed-off-by: Alexander Aring Reviewed-by: Varka Bhadram Acked-by: Stefan Schmidt Acked-by: Varka Bhadram Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- drivers/net/ieee802154/atusb.c | 2 +- drivers/net/ieee802154/cc2520.c | 3 +-- drivers/net/ieee802154/mrf24j40.c | 3 +-- 4 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 6e20e9c94b3c..1bf86d2df23f 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1443,7 +1443,7 @@ at86rf230_detect_device(struct at86rf230_local *lp) return -EINVAL; } - lp->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AACK | + lp->hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_CSMA_PARAMS | IEEE802154_HW_FRAME_RETRIES | IEEE802154_HW_AFILT | IEEE802154_HW_PROMISCUOUS; diff --git a/drivers/net/ieee802154/atusb.c b/drivers/net/ieee802154/atusb.c index 3d25678dfd95..80dfc725b8dc 100644 --- a/drivers/net/ieee802154/atusb.c +++ b/drivers/net/ieee802154/atusb.c @@ -628,7 +628,7 @@ static int atusb_probe(struct usb_interface *interface, hw->parent = &usb_dev->dev; hw->flags = IEEE802154_HW_TX_OMIT_CKSUM | IEEE802154_HW_AFILT | - IEEE802154_HW_AACK | IEEE802154_HW_PROMISCUOUS; + IEEE802154_HW_PROMISCUOUS; hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index a8bafd6bd5e4..15f263cfece5 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -746,8 +746,7 @@ static int cc2520_register(struct cc2520_private *priv) /* We do support only 2.4 Ghz */ priv->hw->phy->supported.channels[0] = 0x7FFF800; - priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | - IEEE802154_HW_AFILT; + priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AFILT; priv->hw->phy->flags = WPAN_PHY_FLAG_TXPOWER; diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index f2a1bd122a74..99c767695c7b 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -751,8 +751,7 @@ static int mrf24j40_probe(struct spi_device *spi) devrec->hw->priv = devrec; devrec->hw->parent = &devrec->spi->dev; devrec->hw->phy->supported.channels[0] = CHANNEL_MASK; - devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK | - IEEE802154_HW_AFILT; + devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AFILT; dev_dbg(printdev(devrec), "registered mrf24j40\n"); ret = ieee802154_register_hw(devrec->hw); -- cgit v1.2.3 From 692c062e7c282164fd7cda68077f79dafd176eaf Mon Sep 17 00:00:00 2001 From: Dmitry Tunin Date: Sat, 6 Jun 2015 20:25:40 +0300 Subject: ath3k: Add support of 0489:e076 AR3012 device BugLink: https://bugs.launchpad.net/bugs/1462614 This device requires new firmware files AthrBT_0x11020100.dfu and ramps_0x11020100_40.dfu added to /lib/firmware/ar3k/ that are not included in linux-firmware yet. T: Bus=03 Lev=01 Prnt=01 Port=09 Cnt=06 Dev#= 7 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0489 ProdID=e076 Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=(none) E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Dmitry Tunin Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 8c81af6dbe06..ee64764663f4 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -80,6 +80,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0489, 0xe057) }, { USB_DEVICE(0x0489, 0xe056) }, { USB_DEVICE(0x0489, 0xe05f) }, + { USB_DEVICE(0x0489, 0xe076) }, { USB_DEVICE(0x0489, 0xe078) }, { USB_DEVICE(0x04c5, 0x1330) }, { USB_DEVICE(0x04CA, 0x3004) }, @@ -137,6 +138,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 94c6c048130f..c9be776133e0 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -179,6 +179,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0489, 0xe076), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3 From 0d0cef6183aec0fb6d0c9f00a09ff51ee086bbe2 Mon Sep 17 00:00:00 2001 From: Dmitry Tunin Date: Sat, 6 Jun 2015 20:29:25 +0300 Subject: ath3k: add support of 13d3:3474 AR3012 device BugLink: https://bugs.launchpad.net/bugs/1427680 This device requires new firmware files AthrBT_0x11020100.dfu and ramps_0x11020100_40.dfu added to /lib/firmware/ar3k/ that are not included in linux-firmware yet. T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 4 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=13d3 ProdID=3474 Rev=00.01 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb Signed-off-by: Dmitry Tunin Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index ee64764663f4..2fa6588e94de 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -114,6 +114,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x13d3, 0x3408) }, { USB_DEVICE(0x13d3, 0x3423) }, { USB_DEVICE(0x13d3, 0x3432) }, + { USB_DEVICE(0x13d3, 0x3474) }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xE02C) }, @@ -172,6 +173,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU22 with sflash firmware */ { USB_DEVICE(0x0489, 0xE036), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c9be776133e0..c956250176b3 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -213,6 +213,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, /* Atheros AR5BBU12 with sflash firmware */ { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, -- cgit v1.2.3 From ecffc80478cdce122f0ecb6a4e4f909132dd5c47 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Jun 2015 09:42:19 +0200 Subject: Bluetooth: btusb: Fix memory leak in Intel setup routine The SKB returned from the Intel specific version information command is missing a kfree_skb. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org --- drivers/bluetooth/btusb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index c956250176b3..7f936db169f5 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1616,6 +1616,8 @@ static int btusb_setup_intel(struct hci_dev *hdev) } fw_ptr = fw->data; + kfree_skb(skb); + /* This Intel specific command enables the manufacturer mode of the * controller. * -- cgit v1.2.3 From 9641d3435f76dfa9255974acebc64d5794889e77 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Jun 2015 10:01:01 +0200 Subject: Bluetooth: btusb: Remove double error check from local version command The __hci_cmd_sync function already handles the command status and command complete errors. No need to check the status field again. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/btusb.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7f936db169f5..317b276441af 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1344,7 +1344,6 @@ static int btusb_setup_csr(struct hci_dev *hdev) { struct hci_rp_read_local_version *rp; struct sk_buff *skb; - int ret; BT_DBG("%s", hdev->name); @@ -1354,26 +1353,21 @@ static int btusb_setup_csr(struct hci_dev *hdev) rp = (struct hci_rp_read_local_version *)skb->data; - if (!rp->status) { - if (le16_to_cpu(rp->manufacturer) != 10) { - /* Clear the reset quirk since this is not an actual - * early Bluetooth 1.1 device from CSR. - */ - clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); + if (le16_to_cpu(rp->manufacturer) != 10) { + /* Clear the reset quirk since this is not an actual + * early Bluetooth 1.1 device from CSR. + */ + clear_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); - /* These fake CSR controllers have all a broken - * stored link key handling and so just disable it. - */ - set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, - &hdev->quirks); - } + /* These fake CSR controllers have all a broken + * stored link key handling and so just disable it. + */ + set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks); } - ret = -bt_to_errno(rp->status); - kfree_skb(skb); - return ret; + return 0; } static const struct firmware *btusb_setup_intel_get_fw(struct hci_dev *hdev, -- cgit v1.2.3 From 7cd84d7209e54b7c6a95572ce09af15126dcacaf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Jun 2015 10:01:02 +0200 Subject: Bluetooth: btusb: Remove unneeded btusb_read_local_version function The btusb_read_local_version function has only a single user and with that just move its functionality in place where it belongs. Signed-off-by: Marcel Holtmann Signed-off-by: Johan Hedberg --- drivers/bluetooth/btusb.c | 38 +++++++++++++------------------------- 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 317b276441af..2df43cf4a383 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1302,28 +1302,6 @@ static void btusb_waker(struct work_struct *work) 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) { struct sk_buff *skb; @@ -1347,9 +1325,19 @@ static int btusb_setup_csr(struct hci_dev *hdev) BT_DBG("%s", hdev->name); - skb = btusb_read_local_version(hdev); - if (IS_ERR(skb)) - return -PTR_ERR(skb); + skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + int err = PTR_ERR(skb); + BT_ERR("%s: CSR: Local version failed (%d)", hdev->name, err); + return err; + } + + if (skb->len != sizeof(struct hci_rp_read_local_version)) { + BT_ERR("%s: CSR: Local version length mismatch", hdev->name); + kfree_skb(skb); + return -EIO; + } rp = (struct hci_rp_read_local_version *)skb->data; -- cgit v1.2.3 From 2eeac871697ac24a77b6d7953bd711b490e83ac7 Mon Sep 17 00:00:00 2001 From: Aleksei Volkov Date: Mon, 8 Jun 2015 12:02:10 +0300 Subject: Bluetooth: btusb: Correct typo in Roper Class 1 Bluetooth Dongle That patch corrects the typo in usb vendor id for Roper Class 1 Bluetooth Dongle. Problem with typo is present since 4.0 kernel. Content /sys/kernel/debug/usb/devices for these dongle: T: Bus=05 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=1310 ProdID=0001 Rev=15.00 S: Manufacturer=SiW S: Product=SiW S: SerialNumber=E7BB050D0B00 C:* #Ifs= 2 Cfg#= 1 Atr=a0 MxPwr= 50mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Aleksei Volkov Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org # 4.0.x --- drivers/bluetooth/btusb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 2df43cf4a383..70c06e6d7346 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -268,7 +268,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0e5e, 0x6622), .driver_info = BTUSB_BROKEN_ISOC }, /* Roper Class 1 Bluetooth Dongle (Silicon Wave based) */ - { USB_DEVICE(0x1300, 0x0001), .driver_info = BTUSB_SWAVE }, + { USB_DEVICE(0x1310, 0x0001), .driver_info = BTUSB_SWAVE }, /* Digianswer devices */ { USB_DEVICE(0x08fd, 0x0001), .driver_info = BTUSB_DIGIANSWER }, -- cgit v1.2.3 From e66890a96abbb746e1229c3067471be36dc49b34 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 7 Jun 2015 09:47:08 +0200 Subject: Bluetooth: btusb: Fix secure send command length alignment on Intel 8260 This patch fixes the command length alignment issue for Intel Bluetooth 8260. The length of parameters in the firmware downloading command must be multiplication of 4. If not, the command must append Intel_NOP command with extra parameters, zeros, at the end, and the firmware file is already included Intel_NOP command for alignment. This patch checks the next command and if the next command is Intel_NOP command, it reads the Intel_NOP command and send them together. For example, if the data from the firmware file looks like this: 8E FC 03 11 22 33 02 FC 03 00 00 00 Previously, btusb sends two commands: 09 FC 06 8E FC 03 11 22 33 09 FC 06 02 FC 03 00 00 00 This won't work because the length of parameters are 6 which violates the 4 byte alignment. This patch will append them together and send as one command: 09 FC 0C 8E FC 03 11 22 33 02 FC 03 00 00 00 Based on previous work from Tedd Ho-Jeong An Reported-by: Tedd Ho-Jeong An Signed-off-by: Marcel Holtmann Tested-by: Tedd Ho-Jeong An Signed-off-by: Johan Hedberg Cc: stable@vger.kernel.org --- drivers/bluetooth/btusb.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 70c06e6d7346..e97d036cde70 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -1932,6 +1932,7 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) struct intel_boot_params *params; const struct firmware *fw; const u8 *fw_ptr; + u32 frag_len; char fwname[64]; ktime_t calltime, delta, rettime; unsigned long long duration; @@ -2124,24 +2125,33 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) } fw_ptr = fw->data + 644; + frag_len = 0; while (fw_ptr - fw->data < fw->size) { - struct hci_command_hdr *cmd = (void *)fw_ptr; - u8 cmd_len; + struct hci_command_hdr *cmd = (void *)(fw_ptr + frag_len); - cmd_len = sizeof(*cmd) + cmd->plen; + frag_len += sizeof(*cmd) + cmd->plen; - /* Send each command from the firmware data buffer as - * a single Data fragment. + /* The paramter length of the secure send command requires + * a 4 byte alignment. It happens so that the firmware file + * contains proper Intel_NOP commands to align the fragments + * as needed. + * + * Send set of commands with 4 byte alignment from the + * firmware data buffer as a single Data fragement. */ - err = btusb_intel_secure_send(hdev, 0x01, cmd_len, fw_ptr); - if (err < 0) { - BT_ERR("%s: Failed to send firmware data (%d)", - hdev->name, err); - goto done; - } + if (!(frag_len % 4)) { + err = btusb_intel_secure_send(hdev, 0x01, frag_len, + fw_ptr); + if (err < 0) { + BT_ERR("%s: Failed to send firmware data (%d)", + hdev->name, err); + goto done; + } - fw_ptr += cmd_len; + fw_ptr += frag_len; + frag_len = 0; + } } set_bit(BTUSB_FIRMWARE_LOADED, &data->flags); -- cgit v1.2.3 From e5719b661a978f7d23042c140979351951f970bb Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 9 Jun 2015 10:52:26 +0200 Subject: ieee802154/mrf24j40: make sure we do not override return values If we run into an error during rx we set the the error code in ret, but override it afterwards. Using a different variable for the extra case avoids this situation. CID: 1226982, 1226983 Signed-off-by: Stefan Schmidt Cc: Alan Ott Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/mrf24j40.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/mrf24j40.c b/drivers/net/ieee802154/mrf24j40.c index 99c767695c7b..2549760e039f 100644 --- a/drivers/net/ieee802154/mrf24j40.c +++ b/drivers/net/ieee802154/mrf24j40.c @@ -533,6 +533,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) u8 lqi = 0; u8 val; int ret = 0; + int ret2; struct sk_buff *skb; /* Turn off reception of packets off the air. This prevents the @@ -569,9 +570,9 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) out: /* Turn back on reception of packets off the air. */ - ret = read_short_reg(devrec, REG_BBREG1, &val); - if (ret) - return ret; + ret2 = read_short_reg(devrec, REG_BBREG1, &val); + if (ret2) + return ret2; val &= ~0x4; /* Clear RXDECINV */ write_short_reg(devrec, REG_BBREG1, val); -- cgit v1.2.3 From fe8de008ecc7c8a6bda72a7c3ac1916c947074b2 Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Tue, 9 Jun 2015 11:51:53 +0000 Subject: Bluetooth: hci_bcsp: Clean up code Fix Fix for spaces prohibited around that '->' reported by checkpatch and space prohibited between function name and open parenthesis '(' Signed-off-by: Prasanna Karthik Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcsp.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index fc0056a28b81..d0b615a932d1 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -436,7 +436,7 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char break; default: memcpy(skb_put(bcsp->rx_skb, 1), &byte, 1); - if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && + if ((bcsp->rx_skb->data[0] & 0x40) != 0 && bcsp->rx_state != BCSP_W4_CRC) bcsp_crc_update(&bcsp->message_crc, byte); bcsp->rx_count--; @@ -447,24 +447,24 @@ static inline void bcsp_unslip_one_byte(struct bcsp_struct *bcsp, unsigned char switch (byte) { case 0xdc: memcpy(skb_put(bcsp->rx_skb, 1), &c0, 1); - if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && + if ((bcsp->rx_skb->data[0] & 0x40) != 0 && bcsp->rx_state != BCSP_W4_CRC) - bcsp_crc_update(&bcsp-> message_crc, 0xc0); + bcsp_crc_update(&bcsp->message_crc, 0xc0); bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; bcsp->rx_count--; break; case 0xdd: memcpy(skb_put(bcsp->rx_skb, 1), &db, 1); - if ((bcsp->rx_skb-> data[0] & 0x40) != 0 && + if ((bcsp->rx_skb->data[0] & 0x40) != 0 && bcsp->rx_state != BCSP_W4_CRC) - bcsp_crc_update(&bcsp-> message_crc, 0xdb); + bcsp_crc_update(&bcsp->message_crc, 0xdb); bcsp->rx_esc_state = BCSP_ESCSTATE_NOESC; bcsp->rx_count--; break; default: - BT_ERR ("Invalid byte %02x after esc byte", byte); + BT_ERR("Invalid byte %02x after esc byte", byte); kfree_skb(bcsp->rx_skb); bcsp->rx_skb = NULL; bcsp->rx_state = BCSP_W4_PKT_DELIMITER; @@ -527,7 +527,7 @@ static void bcsp_complete_rx_pkt(struct hci_uart *hu) hci_recv_frame(hu->hdev, bcsp->rx_skb); } else { - BT_ERR ("Packet for unknown channel (%u %s)", + BT_ERR("Packet for unknown channel (%u %s)", bcsp->rx_skb->data[1] & 0x0f, bcsp->rx_skb->data[0] & 0x80 ? "reliable" : "unreliable"); @@ -587,7 +587,7 @@ static int bcsp_recv(struct hci_uart *hu, const void *data, int count) } if (bcsp->rx_skb->data[0] & 0x80 /* reliable pkt */ && (bcsp->rx_skb->data[0] & 0x07) != bcsp->rxseq_txack) { - BT_ERR ("Out-of-order packet arrived, got %u expected %u", + BT_ERR("Out-of-order packet arrived, got %u expected %u", bcsp->rx_skb->data[0] & 0x07, bcsp->rxseq_txack); kfree_skb(bcsp->rx_skb); -- cgit v1.2.3 From c9d442038ef729549e1fd14ff1d61d0d3a7f0560 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Tue, 9 Jun 2015 11:49:27 +0200 Subject: ieee802154: cc2520: check for return values in cc2520_filter() neither ram nor register write return values have been checked here. Checking both now. Assign ret with 0 as all other assignments are inside if blocks and might not happen before we return ret. CID: 1230469 Signed-off-by: Stefan Schmidt Acked-by: Varka Bhadram Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/cc2520.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c index 15f263cfece5..b6fc29579667 100644 --- a/drivers/net/ieee802154/cc2520.c +++ b/drivers/net/ieee802154/cc2520.c @@ -590,22 +590,23 @@ cc2520_filter(struct ieee802154_hw *hw, struct ieee802154_hw_addr_filt *filt, unsigned long changed) { struct cc2520_private *priv = hw->priv; + int ret = 0; if (changed & IEEE802154_AFILT_PANID_CHANGED) { u16 panid = le16_to_cpu(filt->pan_id); dev_vdbg(&priv->spi->dev, "cc2520_filter called for pan id\n"); - cc2520_write_ram(priv, CC2520RAM_PANID, - sizeof(panid), (u8 *)&panid); + ret = cc2520_write_ram(priv, CC2520RAM_PANID, + sizeof(panid), (u8 *)&panid); } if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for IEEE addr\n"); - cc2520_write_ram(priv, CC2520RAM_IEEEADDR, - sizeof(filt->ieee_addr), - (u8 *)&filt->ieee_addr); + ret = cc2520_write_ram(priv, CC2520RAM_IEEEADDR, + sizeof(filt->ieee_addr), + (u8 *)&filt->ieee_addr); } if (changed & IEEE802154_AFILT_SADDR_CHANGED) { @@ -613,20 +614,22 @@ cc2520_filter(struct ieee802154_hw *hw, dev_vdbg(&priv->spi->dev, "cc2520_filter called for saddr\n"); - cc2520_write_ram(priv, CC2520RAM_SHORTADDR, - sizeof(addr), (u8 *)&addr); + ret = cc2520_write_ram(priv, CC2520RAM_SHORTADDR, + sizeof(addr), (u8 *)&addr); } if (changed & IEEE802154_AFILT_PANC_CHANGED) { dev_vdbg(&priv->spi->dev, "cc2520_filter called for panc change\n"); if (filt->pan_coord) - cc2520_write_register(priv, CC2520_FRMFILT0, 0x02); + ret = cc2520_write_register(priv, CC2520_FRMFILT0, + 0x02); else - cc2520_write_register(priv, CC2520_FRMFILT0, 0x00); + ret = cc2520_write_register(priv, CC2520_FRMFILT0, + 0x00); } - return 0; + return ret; } static inline int cc2520_set_tx_power(struct cc2520_private *priv, s32 mbm) -- cgit v1.2.3 From 61b2fc2bb53f162121f4267f10d2a662911f3e86 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Tue, 9 Jun 2015 16:15:37 +0200 Subject: Bluetooth: hci_uart: Add bcm_set_baudrate() Add vendor specific command to change controller device speed. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.h | 12 ++++++++++ drivers/bluetooth/hci_bcm.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index f405f8424399..02f5f9665411 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -21,6 +21,18 @@ * */ +#define BCM_UART_CLOCK_48MHZ 0x01 +#define BCM_UART_CLOCK_24MHZ 0x02 + +struct bcm_update_uart_baud_rate { + __le16 zero; + __le32 baud_rate; +} __packed; + +struct bcm_write_uart_clock_setting { + __u8 type; +} __packed; + #if IS_ENABLED(CONFIG_BT_BCM) int btbcm_check_bdaddr(struct hci_dev *hdev); diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index 070452256816..e4d66b61cda0 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -37,6 +37,55 @@ struct bcm_data { struct sk_buff_head txq; }; +static int bcm_set_baudrate(struct hci_uart *hu, unsigned int speed) +{ + struct hci_dev *hdev = hu->hdev; + struct sk_buff *skb; + struct bcm_update_uart_baud_rate param; + + if (speed > 3000000) { + struct bcm_write_uart_clock_setting clock; + + clock.type = BCM_UART_CLOCK_48MHZ; + + BT_DBG("%s: Set Controller clock (%d)", hdev->name, clock.type); + + /* This Broadcom specific command changes the UART's controller + * clock for baud rate > 3000000. + */ + skb = __hci_cmd_sync(hdev, 0xfc45, 1, &clock, HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + int err = PTR_ERR(skb); + BT_ERR("%s: BCM: failed to write clock command (%d)", + hdev->name, err); + return err; + } + + kfree_skb(skb); + } + + BT_DBG("%s: Set Controller UART speed to %d bit/s", hdev->name, speed); + + param.zero = cpu_to_le16(0); + param.baud_rate = cpu_to_le32(speed); + + /* This Broadcom specific command changes the UART's controller baud + * rate. + */ + skb = __hci_cmd_sync(hdev, 0xfc18, sizeof(param), ¶m, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + int err = PTR_ERR(skb); + BT_ERR("%s: BCM: failed to write update baudrate command (%d)", + hdev->name, err); + return err; + } + + kfree_skb(skb); + + return 0; +} + static int bcm_open(struct hci_uart *hu) { struct bcm_data *bcm; @@ -107,6 +156,12 @@ static int bcm_setup(struct hci_uart *hu) if (hu->proto->init_speed) hci_uart_set_baudrate(hu, hu->proto->init_speed); + if (hu->proto->oper_speed) { + err = bcm_set_baudrate(hu, hu->proto->oper_speed); + if (!err) + hci_uart_set_baudrate(hu, hu->proto->oper_speed); + } + finalize: release_firmware(fw); @@ -162,10 +217,13 @@ static struct sk_buff *bcm_dequeue(struct hci_uart *hu) static const struct hci_uart_proto bcm_proto = { .id = HCI_UART_BCM, .name = "BCM", + .init_speed = 115200, + .oper_speed = 4000000, .open = bcm_open, .close = bcm_close, .flush = bcm_flush, .setup = bcm_setup, + .set_baudrate = bcm_set_baudrate, .recv = bcm_recv, .enqueue = bcm_enqueue, .dequeue = bcm_dequeue, -- cgit v1.2.3 From 9ff19e6f44e370d9ac20c2cc677724e44d76f2c6 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 13 Jun 2015 22:15:53 +0200 Subject: at86rf230: use level high as fallback default This patch use high level interrupt type as fallback handling when no irq type is given. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 1bf86d2df23f..25e1edecc24b 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -1633,7 +1633,7 @@ static int at86rf230_probe(struct spi_device *spi) irq_type = irq_get_trigger_type(spi->irq); if (!irq_type) - irq_type = IRQF_TRIGGER_RISING; + irq_type = IRQF_TRIGGER_HIGH; rc = devm_request_irq(&spi->dev, spi->irq, at86rf230_isr, IRQF_SHARED | irq_type, dev_name(&spi->dev), lp); -- cgit v1.2.3 From e6f7ed9dc1164c2f20bd984e251cf4dd5ff61d2c Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sat, 13 Jun 2015 22:15:54 +0200 Subject: at86rf230: add support for sleep state This patch adds support for sleep state when between stop and start period. In this period the transceiver isn't used by the subsystem, in this time we disable the irq and going into the sleep state. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 25e1edecc24b..6b31f4708122 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -47,6 +47,8 @@ struct at86rf2xx_chip_data { u16 t_reset_to_off; u16 t_off_to_aack; u16 t_off_to_tx_on; + u16 t_off_to_sleep; + u16 t_sleep_to_off; u16 t_frame; u16 t_p_ack; int rssi_base_val; @@ -869,13 +871,33 @@ at86rf230_ed(struct ieee802154_hw *hw, u8 *level) static int at86rf230_start(struct ieee802154_hw *hw) { + struct at86rf230_local *lp = hw->priv; + + if (gpio_is_valid(lp->slp_tr)) { + gpio_set_value(lp->slp_tr, 0); + usleep_range(lp->data->t_sleep_to_off, + lp->data->t_sleep_to_off + 100); + } + + enable_irq(lp->spi->irq); + return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); } static void at86rf230_stop(struct ieee802154_hw *hw) { + struct at86rf230_local *lp = hw->priv; + at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); + + disable_irq(lp->spi->irq); + + if (gpio_is_valid(lp->slp_tr)) { + gpio_set_value(lp->slp_tr, 1); + usleep_range(lp->data->t_off_to_sleep, + lp->data->t_off_to_sleep + 10); + } } static int @@ -1241,6 +1263,8 @@ static struct at86rf2xx_chip_data at86rf233_data = { .t_reset_to_off = 26, .t_off_to_aack = 80, .t_off_to_tx_on = 80, + .t_off_to_sleep = 35, + .t_sleep_to_off = 210, .t_frame = 4096, .t_p_ack = 545, .rssi_base_val = -91, @@ -1254,6 +1278,8 @@ static struct at86rf2xx_chip_data at86rf231_data = { .t_reset_to_off = 37, .t_off_to_aack = 110, .t_off_to_tx_on = 110, + .t_off_to_sleep = 35, + .t_sleep_to_off = 380, .t_frame = 4096, .t_p_ack = 545, .rssi_base_val = -91, @@ -1267,6 +1293,8 @@ static struct at86rf2xx_chip_data at86rf212_data = { .t_reset_to_off = 26, .t_off_to_aack = 200, .t_off_to_tx_on = 200, + .t_off_to_sleep = 35, + .t_sleep_to_off = 380, .t_frame = 4096, .t_p_ack = 545, .rssi_base_val = -100, @@ -1640,6 +1668,16 @@ static int at86rf230_probe(struct spi_device *spi) if (rc) goto free_dev; + /* disable_irq by default and wait for starting hardware */ + disable_irq(spi->irq); + + /* going into sleep by default */ + if (gpio_is_valid(slp_tr)) { + gpio_set_value(slp_tr, 1); + usleep_range(lp->data->t_off_to_sleep, + lp->data->t_off_to_sleep + 10); + } + rc = ieee802154_register_hw(lp->hw); if (rc) goto free_dev; -- cgit v1.2.3 From 789a99ecb9cb700eb8f07b9d106b99e705e99471 Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Sun, 14 Jun 2015 16:48:44 +0200 Subject: fakelb: add xmit_async after stop testcase This patch adds a suspended testcase into the xmit_async functionality. In the hope that we can found race conditions when xmit_async is called after an ieee802154_ops stop. This should never happen. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/fakelb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/fakelb.c b/drivers/net/ieee802154/fakelb.c index 9d0da4ec3e8c..860d4aed8274 100644 --- a/drivers/net/ieee802154/fakelb.c +++ b/drivers/net/ieee802154/fakelb.c @@ -41,6 +41,8 @@ struct fakelb_phy { u8 page; u8 channel; + bool suspended; + struct list_head list; struct list_head list_ifup; }; @@ -69,6 +71,7 @@ static int fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb) struct fakelb_phy *current_phy = hw->priv, *phy; read_lock_bh(&fakelb_ifup_phys_lock); + WARN_ON(current_phy->suspended); list_for_each_entry(phy, &fakelb_ifup_phys, list_ifup) { if (current_phy == phy) continue; @@ -92,6 +95,7 @@ static int fakelb_hw_start(struct ieee802154_hw *hw) struct fakelb_phy *phy = hw->priv; write_lock_bh(&fakelb_ifup_phys_lock); + phy->suspended = false; list_add(&phy->list_ifup, &fakelb_ifup_phys); write_unlock_bh(&fakelb_ifup_phys_lock); @@ -103,6 +107,7 @@ static void fakelb_hw_stop(struct ieee802154_hw *hw) struct fakelb_phy *phy = hw->priv; write_lock_bh(&fakelb_ifup_phys_lock); + phy->suspended = true; list_del(&phy->list_ifup); write_unlock_bh(&fakelb_ifup_phys_lock); } -- cgit v1.2.3 From cbe6234689b07f5d1ecf2281573591ca4211a5cf Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 16 Jun 2015 11:07:42 +0200 Subject: at86rf230: fix phy settings while sleeping While in sleep state then we can't access the at86rf2xx registers. This patch checks if the transceiver is in sleep state before sending spi messages via regmap. Regmap is used on every driver ops callback except for receive and xmit handling, but while receive and xmit handling the phy should not be inside the sleep state. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 88 +++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 6b31f4708122..b839bbd4ff69 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -90,6 +90,7 @@ struct at86rf230_local { struct at86rf2xx_chip_data *data; struct regmap *regmap; int slp_tr; + bool sleep; struct completion state_complete; struct at86rf230_state_change state; @@ -114,18 +115,66 @@ at86rf230_async_state_change(struct at86rf230_local *lp, const u8 state, void (*complete)(void *context), const bool irq_enable); +static inline void +at86rf230_sleep(struct at86rf230_local *lp) +{ + if (gpio_is_valid(lp->slp_tr)) { + gpio_set_value(lp->slp_tr, 1); + usleep_range(lp->data->t_off_to_sleep, + lp->data->t_off_to_sleep + 10); + lp->sleep = true; + } +} + +static inline void +at86rf230_awake(struct at86rf230_local *lp) +{ + if (gpio_is_valid(lp->slp_tr)) { + gpio_set_value(lp->slp_tr, 0); + usleep_range(lp->data->t_sleep_to_off, + lp->data->t_sleep_to_off + 100); + lp->sleep = false; + } +} + static inline int __at86rf230_write(struct at86rf230_local *lp, unsigned int addr, unsigned int data) { - return regmap_write(lp->regmap, addr, data); + bool sleep = lp->sleep; + int ret; + + /* awake for register setting if sleep */ + if (sleep) + at86rf230_awake(lp); + + ret = regmap_write(lp->regmap, addr, data); + + /* sleep again if was sleeping */ + if (sleep) + at86rf230_sleep(lp); + + return ret; } static inline int __at86rf230_read(struct at86rf230_local *lp, unsigned int addr, unsigned int *data) { - return regmap_read(lp->regmap, addr, data); + bool sleep = lp->sleep; + int ret; + + /* awake for register setting if sleep */ + if (sleep) + at86rf230_awake(lp); + + ret = regmap_read(lp->regmap, addr, data); + + /* sleep again if was sleeping */ + if (sleep) + at86rf230_sleep(lp); + + return ret; } static inline int @@ -147,7 +196,20 @@ at86rf230_write_subreg(struct at86rf230_local *lp, unsigned int addr, unsigned int mask, unsigned int shift, unsigned int data) { - return regmap_update_bits(lp->regmap, addr, mask, data << shift); + bool sleep = lp->sleep; + int ret; + + /* awake for register setting if sleep */ + if (sleep) + at86rf230_awake(lp); + + ret = regmap_update_bits(lp->regmap, addr, mask, data << shift); + + /* sleep again if was sleeping */ + if (sleep) + at86rf230_sleep(lp); + + return ret; } static inline void @@ -873,12 +935,7 @@ at86rf230_start(struct ieee802154_hw *hw) { struct at86rf230_local *lp = hw->priv; - if (gpio_is_valid(lp->slp_tr)) { - gpio_set_value(lp->slp_tr, 0); - usleep_range(lp->data->t_sleep_to_off, - lp->data->t_sleep_to_off + 100); - } - + at86rf230_awake(lp); enable_irq(lp->spi->irq); return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); @@ -892,12 +949,7 @@ at86rf230_stop(struct ieee802154_hw *hw) at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); disable_irq(lp->spi->irq); - - if (gpio_is_valid(lp->slp_tr)) { - gpio_set_value(lp->slp_tr, 1); - usleep_range(lp->data->t_off_to_sleep, - lp->data->t_off_to_sleep + 10); - } + at86rf230_sleep(lp); } static int @@ -1672,11 +1724,7 @@ static int at86rf230_probe(struct spi_device *spi) disable_irq(spi->irq); /* going into sleep by default */ - if (gpio_is_valid(slp_tr)) { - gpio_set_value(slp_tr, 1); - usleep_range(lp->data->t_off_to_sleep, - lp->data->t_off_to_sleep + 10); - } + at86rf230_sleep(lp); rc = ieee802154_register_hw(lp->hw); if (rc) -- cgit v1.2.3 From 74ed9d98456a7a85c9e041cd17350b8583659adf Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 16 Jun 2015 11:07:43 +0200 Subject: at86rf230: add recommended csma backoffs settings This patch adds support for a new random csma backoffs settings when going into sleep state. This is recommended according at86rf2xx datasheets. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index b839bbd4ff69..7e30a45718c9 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -945,10 +945,21 @@ static void at86rf230_stop(struct ieee802154_hw *hw) { struct at86rf230_local *lp = hw->priv; + u8 csma_seed[2]; at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); disable_irq(lp->spi->irq); + + /* It's recommended to set random new csma_seeds before sleep state. + * Makes only sense in the stop callback, not doing this inside of + * at86rf230_sleep, this is also used when we don't transmit afterwards + * when calling start callback again. + */ + get_random_bytes(csma_seed, ARRAY_SIZE(csma_seed)); + at86rf230_write_subreg(lp, SR_CSMA_SEED_0, csma_seed[0]); + at86rf230_write_subreg(lp, SR_CSMA_SEED_1, csma_seed[1]); + at86rf230_sleep(lp); } -- cgit v1.2.3 From 30811fa663d7efa65ccec290b47a1f564485fcdd Mon Sep 17 00:00:00 2001 From: Alexander Aring Date: Tue, 16 Jun 2015 11:07:44 +0200 Subject: at86rf230: cleanup start and stop callbacks This code cleanups the start and stop callbacks by removing hw->priv and using the already dereferenced variable lp which is the same. Signed-off-by: Alexander Aring Signed-off-by: Marcel Holtmann --- drivers/net/ieee802154/at86rf230.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c index 7e30a45718c9..f7bd9f3ddaac 100644 --- a/drivers/net/ieee802154/at86rf230.c +++ b/drivers/net/ieee802154/at86rf230.c @@ -938,7 +938,7 @@ at86rf230_start(struct ieee802154_hw *hw) at86rf230_awake(lp); enable_irq(lp->spi->irq); - return at86rf230_sync_state_change(hw->priv, STATE_RX_AACK_ON); + return at86rf230_sync_state_change(lp, STATE_RX_AACK_ON); } static void @@ -947,7 +947,7 @@ at86rf230_stop(struct ieee802154_hw *hw) struct at86rf230_local *lp = hw->priv; u8 csma_seed[2]; - at86rf230_sync_state_change(hw->priv, STATE_FORCE_TRX_OFF); + at86rf230_sync_state_change(lp, STATE_FORCE_TRX_OFF); disable_irq(lp->spi->irq); -- cgit v1.2.3 From 3713416763dc03e9011a3146c42411189531446f Mon Sep 17 00:00:00 2001 From: Chan-yeol Park Date: Wed, 17 Jun 2015 21:10:39 +0900 Subject: Bluetooth: hci_uart: Fix dereferencing of ERR_PTR If h4_recv_buf() return ERR_PTR instead sk_buff pointer, it should be cleared once PTR_ERR is completed for the further dereference such as h4_recv(), or h4_close(). Signed-off-by: Chan-yeol Park Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ath.c | 1 + drivers/bluetooth/hci_bcm.c | 1 + drivers/bluetooth/hci_h4.c | 1 + 3 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ath.c b/drivers/bluetooth/hci_ath.c index ec8fa0e0f036..6da5e4ca13ea 100644 --- a/drivers/bluetooth/hci_ath.c +++ b/drivers/bluetooth/hci_ath.c @@ -192,6 +192,7 @@ static int ath_recv(struct hci_uart *hu, const void *data, int count) if (IS_ERR(ath->rx_skb)) { int err = PTR_ERR(ath->rx_skb); BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); + ath->rx_skb = NULL; return err; } diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index e4d66b61cda0..aa3c9aca4cb4 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -188,6 +188,7 @@ static int bcm_recv(struct hci_uart *hu, const void *data, int count) if (IS_ERR(bcm->rx_skb)) { int err = PTR_ERR(bcm->rx_skb); BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); + bcm->rx_skb = NULL; return err; } diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c index f7190f01e135..57faddc53645 100644 --- a/drivers/bluetooth/hci_h4.c +++ b/drivers/bluetooth/hci_h4.c @@ -133,6 +133,7 @@ static int h4_recv(struct hci_uart *hu, const void *data, int count) if (IS_ERR(h4->rx_skb)) { int err = PTR_ERR(h4->rx_skb); BT_ERR("%s: Frame reassembly failed (%d)", hu->hdev->name, err); + h4->rx_skb = NULL; return err; } -- cgit v1.2.3 From 52cc916818c86abc0a123bf1e55fd71c32aa042b Mon Sep 17 00:00:00 2001 From: Tedd Ho-Jeong An Date: Fri, 12 Jun 2015 16:20:05 -0700 Subject: Bluetooth: btusb: Add routine for applying Intel DDC parameters This patch adds the routine to apply the DDC parameter from device specific ddc file. Once the device is rest to operational mode, optionally, it can download the device specific configration (DDC) parameters before the BlueZ starts the stack initialization. It opens the DDC file based on HW_VARIANT and DEV_REVISION and send ID/Value with HCI_Intel_Write_DDC command. Format of DDC file DDC file contains one or more number of DDC structure. DDC Structure It has 'Length' field of one octet, DDC 'ID' field of two octets followed by the array of DDC 'Value' that gives the value of parameters itself. 'Length' contains the length of DDC 'ID' and DDC 'Value'. +------------+----------+ | Size(byte) | Name | +------------+----------+ | 1 | Length | +------------+----------+ | 2 | ID | +------------+----------+ | Length - 2 | Value | +------------+----------+ Signed-off-by: Tedd Ho-Jeong An Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btusb.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index e97d036cde70..3970224b3b09 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -2083,6 +2083,12 @@ static int btusb_setup_intel_new(struct hci_dev *hdev) BT_INFO("%s: Found device firmware: %s", hdev->name, fwname); + /* Save the DDC file name for later use to apply once the firmware + * downloading is done. + */ + snprintf(fwname, sizeof(fwname), "intel/ibt-11-%u.ddc", + le16_to_cpu(params->dev_revid)); + kfree_skb(skb); if (fw->size < 644) { @@ -2244,6 +2250,43 @@ done: clear_bit(BTUSB_BOOTLOADER, &data->flags); + /* Once the device is running in operational mode, it needs to apply + * the device configuration (DDC) parameters. + * + * The device can work without DDC parameters, so even if it fails + * to load the file, no need to fail the setup. + */ + err = request_firmware_direct(&fw, fwname, &hdev->dev); + if (err < 0) + return 0; + + BT_INFO("%s: Found Intel DDC parameters: %s", hdev->name, fwname); + + fw_ptr = fw->data; + + /* DDC file contains one or more DDC structure which has + * Length (1 byte), DDC ID (2 bytes), and DDC value (Length - 2). + */ + while (fw->size > fw_ptr - fw->data) { + u8 cmd_plen = fw_ptr[0] + sizeof(u8); + + skb = __hci_cmd_sync(hdev, 0xfc8b, cmd_plen, fw_ptr, + HCI_INIT_TIMEOUT); + if (IS_ERR(skb)) { + BT_ERR("%s: Failed to send Intel_Write_DDC (%ld)", + hdev->name, PTR_ERR(skb)); + release_firmware(fw); + return PTR_ERR(skb); + } + + fw_ptr += cmd_plen; + kfree_skb(skb); + } + + release_firmware(fw); + + BT_INFO("%s: Applying Intel DDC parameters completed", hdev->name); + return 0; } -- cgit v1.2.3 From 40db5f0eddbee3d2a9a05a3b5dc20368cb65ca0f Mon Sep 17 00:00:00 2001 From: Ilya Faenson Date: Wed, 17 Jun 2015 11:42:46 -0400 Subject: Bluetooth: btbcm: Support the BCM4354 Bluetooth UART device Support the BCM4354 chip and introduce vendor specific command parameter definitions. Signed-off-by: Ilya Faenson Signed-off-by: Marcel Holtmann --- drivers/bluetooth/btbcm.c | 2 ++ drivers/bluetooth/btbcm.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 8e2f6b6251c4..1e1a4323a71f 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -243,6 +243,7 @@ static const struct { } bcm_uart_subver_table[] = { { 0x410e, "BCM43341B0" }, /* 002.001.014 */ { 0x4406, "BCM4324B3" }, /* 002.004.006 */ + { 0x610c, "BCM4354" }, /* 003.001.012 */ { } }; @@ -279,6 +280,7 @@ int btbcm_initialize(struct hci_dev *hdev, char *fw_name, size_t len) switch ((rev & 0xf000) >> 12) { case 0: + case 1: case 3: for (i = 0; bcm_uart_subver_table[i].name; i++) { if (subver == bcm_uart_subver_table[i].subver) { diff --git a/drivers/bluetooth/btbcm.h b/drivers/bluetooth/btbcm.h index 02f5f9665411..d9e6b41658e5 100644 --- a/drivers/bluetooth/btbcm.h +++ b/drivers/bluetooth/btbcm.h @@ -33,6 +33,37 @@ struct bcm_write_uart_clock_setting { __u8 type; } __packed; +struct bcm_set_sleep_mode { + __u8 sleep_mode; + __u8 idle_host; + __u8 idle_dev; + __u8 bt_wake_active; + __u8 host_wake_active; + __u8 allow_host_sleep; + __u8 combine_modes; + __u8 tristate_control; + __u8 usb_auto_sleep; + __u8 usb_resume_timeout; + __u8 pulsed_host_wake; + __u8 break_to_host; +} __packed; + +struct bcm_set_pcm_int_params { + __u8 routing; + __u8 rate; + __u8 frame_sync; + __u8 sync_mode; + __u8 clock_mode; +} __packed; + +struct bcm_set_pcm_format_params { + __u8 lsb_first; + __u8 fill_value; + __u8 fill_method; + __u8 fill_num; + __u8 right_justify; +} __packed; + #if IS_ENABLED(CONFIG_BT_BCM) int btbcm_check_bdaddr(struct hci_dev *hdev); -- cgit v1.2.3 From 2a973dfada2bcd61e1ce31612677da1a9ecc2124 Mon Sep 17 00:00:00 2001 From: Ilya Faenson Date: Wed, 17 Jun 2015 17:30:56 -0400 Subject: Bluetooth: hci_uart: Add new line discipline enhancements Added the ability to flow control the UART, improved the UART baud rate setting, transferred the speeds into line discipline from the protocol and introduced the tty init function. Signed-off-by: Ilya Faenson Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_ldisc.c | 108 +++++++++++++++++++++++++++++++++++++++--- drivers/bluetooth/hci_uart.h | 7 +++ 2 files changed, 109 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index ac87346ce9d7..590bd8e66bfb 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -266,6 +266,85 @@ static int hci_uart_send_frame(struct hci_dev *hdev, struct sk_buff *skb) return 0; } +/* Flow control or un-flow control the device */ +void hci_uart_set_flow_control(struct hci_uart *hu, bool enable) +{ + struct tty_struct *tty = hu->tty; + struct ktermios ktermios; + int status; + unsigned int set = 0; + unsigned int clear = 0; + + if (enable) { + /* Disable hardware flow control */ + ktermios = tty->termios; + ktermios.c_cflag &= ~CRTSCTS; + status = tty_set_termios(tty, &ktermios); + BT_DBG("Disabling hardware flow control: %s", + status ? "failed" : "success"); + + /* Clear RTS to prevent the device from sending */ + /* Most UARTs need OUT2 to enable interrupts */ + status = tty->driver->ops->tiocmget(tty); + BT_DBG("Current tiocm 0x%x", status); + + set &= ~(TIOCM_OUT2 | TIOCM_RTS); + clear = ~set; + set &= TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | + TIOCM_OUT2 | TIOCM_LOOP; + clear &= TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | + TIOCM_OUT2 | TIOCM_LOOP; + status = tty->driver->ops->tiocmset(tty, set, clear); + BT_DBG("Clearing RTS: %s", status ? "failed" : "success"); + } else { + /* Set RTS to allow the device to send again */ + status = tty->driver->ops->tiocmget(tty); + BT_DBG("Current tiocm 0x%x", status); + + set |= (TIOCM_OUT2 | TIOCM_RTS); + clear = ~set; + set &= TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | + TIOCM_OUT2 | TIOCM_LOOP; + clear &= TIOCM_DTR | TIOCM_RTS | TIOCM_OUT1 | + TIOCM_OUT2 | TIOCM_LOOP; + status = tty->driver->ops->tiocmset(tty, set, clear); + BT_DBG("Setting RTS: %s", status ? "failed" : "success"); + + /* Re-enable hardware flow control */ + ktermios = tty->termios; + ktermios.c_cflag |= CRTSCTS; + status = tty_set_termios(tty, &ktermios); + BT_DBG("Enabling hardware flow control: %s", + status ? "failed" : "success"); + } +} + +void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed, + unsigned int oper_speed) +{ + hu->init_speed = init_speed; + hu->oper_speed = oper_speed; +} + +void hci_uart_init_tty(struct hci_uart *hu) +{ + struct tty_struct *tty = hu->tty; + struct ktermios ktermios; + + /* Bring the UART into a known 8 bits no parity hw fc state */ + ktermios = tty->termios; + ktermios.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | + INLCR | IGNCR | ICRNL | IXON); + ktermios.c_oflag &= ~OPOST; + ktermios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + ktermios.c_cflag &= ~(CSIZE | PARENB); + ktermios.c_cflag |= CS8; + ktermios.c_cflag |= CRTSCTS; + + /* tty_set_termios() return not checked as it is always 0 */ + tty_set_termios(tty, &ktermios); +} + void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed) { struct tty_struct *tty = hu->tty; @@ -273,13 +352,13 @@ void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed) ktermios = tty->termios; ktermios.c_cflag &= ~CBAUD; - ktermios.c_cflag |= BOTHER; tty_termios_encode_baud_rate(&ktermios, speed, speed); /* tty_set_termios() return not checked as it is always 0 */ tty_set_termios(tty, &ktermios); - BT_DBG("%s: New tty speed: %d", hu->hdev->name, tty->termios.c_ispeed); + BT_DBG("%s: New tty speeds: %d/%d", hu->hdev->name, + tty->termios.c_ispeed, tty->termios.c_ospeed); } static int hci_uart_setup(struct hci_dev *hdev) @@ -287,15 +366,32 @@ static int hci_uart_setup(struct hci_dev *hdev) struct hci_uart *hu = hci_get_drvdata(hdev); struct hci_rp_read_local_version *ver; struct sk_buff *skb; + unsigned int speed; int err; + /* Init speed if any */ if (hu->proto->init_speed) - hci_uart_set_baudrate(hu, hu->proto->init_speed); + speed = hu->proto->init_speed; + else if (hu->init_speed) + speed = hu->init_speed; + else + speed = 0; + + if (speed) + hci_uart_set_baudrate(hu, speed); + + /* Operational speed if any */ + if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; + else if (hu->oper_speed) + speed = hu->oper_speed; + else + speed = 0; - if (hu->proto->set_baudrate && hu->proto->oper_speed) { - err = hu->proto->set_baudrate(hu, hu->proto->oper_speed); + if (hu->proto->set_baudrate && speed) { + err = hu->proto->set_baudrate(hu, speed); if (!err) - hci_uart_set_baudrate(hu, hu->proto->oper_speed); + hci_uart_set_baudrate(hu, speed); } if (hu->proto->setup) diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index e9f970c25304..ce9c670956f5 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h @@ -85,6 +85,9 @@ struct hci_uart { struct sk_buff *tx_skb; unsigned long tx_state; spinlock_t rx_lock; + + unsigned int init_speed; + unsigned int oper_speed; }; /* HCI_UART proto flag bits */ @@ -99,7 +102,11 @@ int hci_uart_register_proto(const struct hci_uart_proto *p); int hci_uart_unregister_proto(const struct hci_uart_proto *p); int hci_uart_tx_wakeup(struct hci_uart *hu); int hci_uart_init_ready(struct hci_uart *hu); +void hci_uart_init_tty(struct hci_uart *hu); void hci_uart_set_baudrate(struct hci_uart *hu, unsigned int speed); +void hci_uart_set_flow_control(struct hci_uart *hu, bool enable); +void hci_uart_set_speeds(struct hci_uart *hu, unsigned int init_speed, + unsigned int oper_speed); #ifdef CONFIG_BT_HCIUART_H4 int h4_init(void); -- cgit v1.2.3 From 960ef1d72f60f1df927768b9818ece6d7d046d64 Mon Sep 17 00:00:00 2001 From: Frederic Danis Date: Thu, 18 Jun 2015 12:43:27 +0200 Subject: Bluetooth: hci_uart: Fix speed selection hu->proto->*speed will always be used for all device where it is set. But hu->*speed should be used if exist, so the test should be swapped. The equivalent change is needed in bcm_setup() of hci_bcm.c. Signed-off-by: Frederic Danis Signed-off-by: Marcel Holtmann --- drivers/bluetooth/hci_bcm.c | 29 +++++++++++++++++++++++------ drivers/bluetooth/hci_ldisc.c | 12 ++++++------ 2 files changed, 29 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c index aa3c9aca4cb4..23523e140a9a 100644 --- a/drivers/bluetooth/hci_bcm.c +++ b/drivers/bluetooth/hci_bcm.c @@ -131,6 +131,7 @@ static int bcm_setup(struct hci_uart *hu) { char fw_name[64]; const struct firmware *fw; + unsigned int speed; int err; BT_DBG("hu %p", hu); @@ -153,13 +154,29 @@ static int bcm_setup(struct hci_uart *hu) goto finalize; } - if (hu->proto->init_speed) - hci_uart_set_baudrate(hu, hu->proto->init_speed); - - if (hu->proto->oper_speed) { - err = bcm_set_baudrate(hu, hu->proto->oper_speed); + /* Init speed if any */ + if (hu->init_speed) + speed = hu->init_speed; + else if (hu->proto->init_speed) + speed = hu->proto->init_speed; + else + speed = 0; + + if (speed) + hci_uart_set_baudrate(hu, speed); + + /* Operational speed if any */ + if (hu->oper_speed) + speed = hu->oper_speed; + else if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; + else + speed = 0; + + if (speed) { + err = bcm_set_baudrate(hu, speed); if (!err) - hci_uart_set_baudrate(hu, hu->proto->oper_speed); + hci_uart_set_baudrate(hu, speed); } finalize: diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 590bd8e66bfb..177dd69fdd95 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c @@ -370,10 +370,10 @@ static int hci_uart_setup(struct hci_dev *hdev) int err; /* Init speed if any */ - if (hu->proto->init_speed) - speed = hu->proto->init_speed; - else if (hu->init_speed) + if (hu->init_speed) speed = hu->init_speed; + else if (hu->proto->init_speed) + speed = hu->proto->init_speed; else speed = 0; @@ -381,10 +381,10 @@ static int hci_uart_setup(struct hci_dev *hdev) hci_uart_set_baudrate(hu, speed); /* Operational speed if any */ - if (hu->proto->oper_speed) - speed = hu->proto->oper_speed; - else if (hu->oper_speed) + if (hu->oper_speed) speed = hu->oper_speed; + else if (hu->proto->oper_speed) + speed = hu->proto->oper_speed; else speed = 0; -- cgit v1.2.3 From aebceccc18bf49f8fb208ac4548b7bd402b6662c Mon Sep 17 00:00:00 2001 From: Prasanna Karthik Date: Thu, 18 Jun 2015 13:51:11 +0000 Subject: Bluetooth: bt3c_cs: Fix coding style -- clean up Fix for braces {} are not necessary for single statement blocks reported by checkpatch Signed-off-by: Prasanna Karthik Signed-off-by: Marcel Holtmann --- drivers/bluetooth/bt3c_cs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index 6de97b3871b0..7aab65427d38 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c @@ -202,9 +202,8 @@ static void bt3c_write_wakeup(struct bt3c_info *info) /* Send frame */ len = bt3c_write(iobase, 256, skb->data, skb->len); - if (len != skb->len) { + if (len != skb->len) BT_ERR("Very strange"); - } kfree_skb(skb); -- cgit v1.2.3 From 7e730c7f3d1f39c25cf5f7cf70c0ff4c28d7bec7 Mon Sep 17 00:00:00 2001 From: Dmitry Tunin Date: Thu, 18 Jun 2015 20:41:51 +0300 Subject: Bluetooth: ath3k: Add support of 04ca:300d AR3012 device BugLink: https://bugs.launchpad.net/bugs/1394368 This device requires new firmware files AthrBT_0x11020100.dfu and ramps_0x11020100_40.dfu added to /lib/firmware/ar3k/ that are not included in linux-firmware yet. T: Bus=02 Lev=01 Prnt=01 Port=04 Cnt=03 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=04ca ProdID=300d Rev= 0.01 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Dmitry Tunin Signed-off-by: Marcel Holtmann Cc: stable@vger.kernel.org --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 2fa6588e94de..e527a3e13939 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -89,6 +89,7 @@ static const struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x04CA, 0x3007) }, { USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x300b) }, + { USB_DEVICE(0x04CA, 0x300d) }, { USB_DEVICE(0x04CA, 0x300f) }, { USB_DEVICE(0x04CA, 0x3010) }, { USB_DEVICE(0x0930, 0x0219) }, @@ -148,6 +149,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 3970224b3b09..b4cf8d9c9dac 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -188,6 +188,7 @@ static const struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3