Skip to content

Commit

Permalink
Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/ker…
Browse files Browse the repository at this point in the history
…nel/git/bluetooth/bluetooth-next

Johan Hedberg says:

====================
pull request: bluetooth-next 2018-08-05

Here's the main bluetooth-next pull request for the 4.19 kernel.

 - Added support for Bluetooth Advertising Extensions
 - Added vendor driver support to hci_h5 HCI driver
 - Added serdev support to hci_h5 driver
 - Added support for Qualcomm wcn3990 controller
 - Added support for RTL8723BS and RTL8723DS controllers
 - btusb: Added new ID for Realtek 8723DE
 - Several other smaller fixes & cleanups

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

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 6, 2018
2 parents add0dec + 6c3711e commit 6277547
Show file tree
Hide file tree
Showing 29 changed files with 3,236 additions and 574 deletions.
29 changes: 27 additions & 2 deletions Documentation/devicetree/bindings/net/qualcomm-bluetooth.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,25 @@ device the slave device is attached to.
Required properties:
- compatible: should contain one of the following:
* "qcom,qca6174-bt"
* "qcom,wcn3990-bt"

Optional properties for compatible string qcom,qca6174-bt:

Optional properties:
- enable-gpios: gpio specifier used to enable chip
- clocks: clock provided to the controller (SUSCLK_32KHZ)

Example:
Required properties for compatible string qcom,wcn3990-bt:

- vddio-supply: VDD_IO supply regulator handle.
- vddxo-supply: VDD_XO supply regulator handle.
- vddrf-supply: VDD_RF supply regulator handle.
- vddch0-supply: VDD_CH0 supply regulator handle.

Optional properties for compatible string qcom,wcn3990-bt:

- max-speed: see Documentation/devicetree/bindings/serial/slave-device.txt

Examples:

serial@7570000 {
label = "BT-UART";
Expand All @@ -28,3 +41,15 @@ serial@7570000 {
clocks = <&divclk4>;
};
};

serial@898000 {
bluetooth {
compatible = "qcom,wcn3990-bt";

vddio-supply = <&vreg_s4a_1p8>;
vddxo-supply = <&vreg_l7a_1p8>;
vddrf-supply = <&vreg_l17a_1p3>;
vddch0-supply = <&vreg_l25a_3p3>;
max-speed = <3200000>;
};
};
1 change: 1 addition & 0 deletions drivers/bluetooth/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ config BT_HCIUART_LL
config BT_HCIUART_3WIRE
bool "Three-wire UART (H5) protocol support"
depends on BT_HCIUART
depends on BT_HCIUART_SERDEV
help
The HCI Three-wire UART Transport Layer makes it possible to
user the Bluetooth HCI over a serial port interface. The HCI
Expand Down
2 changes: 1 addition & 1 deletion drivers/bluetooth/bfusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ static int bfusb_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
count = skb->len;

/* Max HCI frame size seems to be 1511 + 1 */
nskb = bt_skb_alloc(count + 32, GFP_ATOMIC);
nskb = bt_skb_alloc(count + 32, GFP_KERNEL);
if (!nskb) {
BT_ERR("Can't allocate memory for new packet");
return -ENOMEM;
Expand Down
2 changes: 1 addition & 1 deletion drivers/bluetooth/bluecard_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
/* Ericsson baud rate command */
unsigned char cmd[] = { HCI_COMMAND_PKT, 0x09, 0xfc, 0x01, 0x03 };

skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_KERNEL);
if (!skb) {
BT_ERR("Can't allocate mem for new packet");
return -1;
Expand Down
6 changes: 3 additions & 3 deletions drivers/bluetooth/bpa10x.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)

skb->dev = (void *) hdev;

urb = usb_alloc_urb(0, GFP_ATOMIC);
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb)
return -ENOMEM;

Expand All @@ -298,7 +298,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)

switch (hci_skb_pkt_type(skb)) {
case HCI_COMMAND_PKT:
dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
dr = kmalloc(sizeof(*dr), GFP_KERNEL);
if (!dr) {
usb_free_urb(urb);
return -ENOMEM;
Expand Down Expand Up @@ -343,7 +343,7 @@ static int bpa10x_send_frame(struct hci_dev *hdev, struct sk_buff *skb)

usb_anchor_urb(urb, &data->tx_anchor);

err = usb_submit_urb(urb, GFP_ATOMIC);
err = usb_submit_urb(urb, GFP_KERNEL);
if (err < 0) {
bt_dev_err(hdev, "urb %p submission failed", urb);
kfree(urb->setup_packet);
Expand Down
2 changes: 1 addition & 1 deletion drivers/bluetooth/btmrvl_sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv)
}

/* Allocate buffer */
skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_ATOMIC);
skb = bt_skb_alloc(num_blocks * blksz + BTSDIO_DMA_ALIGN, GFP_KERNEL);
if (!skb) {
BT_ERR("No free skb");
ret = -ENOMEM;
Expand Down
117 changes: 64 additions & 53 deletions drivers/bluetooth/btqca.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,44 +27,43 @@

#define VERSION "0.1"

static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version)
int qca_read_soc_version(struct hci_dev *hdev, u32 *soc_version)
{
struct sk_buff *skb;
struct edl_event_hdr *edl;
struct rome_version *ver;
char cmd;
int err = 0;

BT_DBG("%s: ROME Patch Version Request", hdev->name);
bt_dev_dbg(hdev, "QCA Version Request");

cmd = EDL_PATCH_VER_REQ_CMD;
skb = __hci_cmd_sync_ev(hdev, EDL_PATCH_CMD_OPCODE, EDL_PATCH_CMD_LEN,
&cmd, HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
BT_ERR("%s: Failed to read version of ROME (%d)", hdev->name,
err);
bt_dev_err(hdev, "Reading QCA version information failed (%d)",
err);
return err;
}

if (skb->len != sizeof(*edl) + sizeof(*ver)) {
BT_ERR("%s: Version size mismatch len %d", hdev->name,
skb->len);
bt_dev_err(hdev, "QCA Version size mismatch len %d", skb->len);
err = -EILSEQ;
goto out;
}

edl = (struct edl_event_hdr *)(skb->data);
if (!edl) {
BT_ERR("%s: TLV with no header", hdev->name);
bt_dev_err(hdev, "QCA TLV with no header");
err = -EILSEQ;
goto out;
}

if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
edl->rtype != EDL_APP_VER_RES_EVT) {
BT_ERR("%s: Wrong packet received %d %d", hdev->name,
edl->cresp, edl->rtype);
bt_dev_err(hdev, "QCA Wrong packet received %d %d", edl->cresp,
edl->rtype);
err = -EIO;
goto out;
}
Expand All @@ -76,30 +75,35 @@ static int rome_patch_ver_req(struct hci_dev *hdev, u32 *rome_version)
BT_DBG("%s: ROM :0x%08x", hdev->name, le16_to_cpu(ver->rome_ver));
BT_DBG("%s: SOC :0x%08x", hdev->name, le32_to_cpu(ver->soc_id));

/* ROME chipset version can be decided by patch and SoC
/* QCA chipset version can be decided by patch and SoC
* version, combination with upper 2 bytes from SoC
* and lower 2 bytes from patch will be used.
*/
*rome_version = (le32_to_cpu(ver->soc_id) << 16) |
*soc_version = (le32_to_cpu(ver->soc_id) << 16) |
(le16_to_cpu(ver->rome_ver) & 0x0000ffff);
if (*soc_version == 0)
err = -EILSEQ;

out:
kfree_skb(skb);
if (err)
bt_dev_err(hdev, "QCA Failed to get version (%d)", err);

return err;
}
EXPORT_SYMBOL_GPL(qca_read_soc_version);

static int rome_reset(struct hci_dev *hdev)
static int qca_send_reset(struct hci_dev *hdev)
{
struct sk_buff *skb;
int err;

BT_DBG("%s: ROME HCI_RESET", hdev->name);
bt_dev_dbg(hdev, "QCA HCI_RESET");

skb = __hci_cmd_sync(hdev, HCI_OP_RESET, 0, NULL, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
BT_ERR("%s: Reset failed (%d)", hdev->name, err);
bt_dev_err(hdev, "QCA Reset failed (%d)", err);
return err;
}

Expand All @@ -108,7 +112,7 @@ static int rome_reset(struct hci_dev *hdev)
return 0;
}

static void rome_tlv_check_data(struct rome_config *config,
static void qca_tlv_check_data(struct rome_config *config,
const struct firmware *fw)
{
const u8 *data;
Expand Down Expand Up @@ -207,7 +211,7 @@ static void rome_tlv_check_data(struct rome_config *config,
}
}

static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size,
static int qca_tlv_send_segment(struct hci_dev *hdev, int seg_size,
const u8 *data, enum rome_tlv_dnld_mode mode)
{
struct sk_buff *skb;
Expand All @@ -228,19 +232,19 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size,
HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
BT_ERR("%s: Failed to send TLV segment (%d)", hdev->name, err);
bt_dev_err(hdev, "QCA Failed to send TLV segment (%d)", err);
return err;
}

if (skb->len != sizeof(*edl) + sizeof(*tlv_resp)) {
BT_ERR("%s: TLV response size mismatch", hdev->name);
bt_dev_err(hdev, "QCA TLV response size mismatch");
err = -EILSEQ;
goto out;
}

edl = (struct edl_event_hdr *)(skb->data);
if (!edl) {
BT_ERR("%s: TLV with no header", hdev->name);
bt_dev_err(hdev, "TLV with no header");
err = -EILSEQ;
goto out;
}
Expand All @@ -249,8 +253,8 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size,

if (edl->cresp != EDL_CMD_REQ_RES_EVT ||
edl->rtype != EDL_TVL_DNLD_RES_EVT || tlv_resp->result != 0x00) {
BT_ERR("%s: TLV with error stat 0x%x rtype 0x%x (0x%x)",
hdev->name, edl->cresp, edl->rtype, tlv_resp->result);
bt_dev_err(hdev, "QCA TLV with error stat 0x%x rtype 0x%x (0x%x)",
edl->cresp, edl->rtype, tlv_resp->result);
err = -EIO;
}

Expand All @@ -260,23 +264,23 @@ static int rome_tlv_send_segment(struct hci_dev *hdev, int seg_size,
return err;
}

static int rome_download_firmware(struct hci_dev *hdev,
static int qca_download_firmware(struct hci_dev *hdev,
struct rome_config *config)
{
const struct firmware *fw;
const u8 *segment;
int ret, remain, i = 0;

bt_dev_info(hdev, "ROME Downloading %s", config->fwname);
bt_dev_info(hdev, "QCA Downloading %s", config->fwname);

ret = request_firmware(&fw, config->fwname, &hdev->dev);
if (ret) {
BT_ERR("%s: Failed to request file: %s (%d)", hdev->name,
config->fwname, ret);
bt_dev_err(hdev, "QCA Failed to request file: %s (%d)",
config->fwname, ret);
return ret;
}

rome_tlv_check_data(config, fw);
qca_tlv_check_data(config, fw);

segment = fw->data;
remain = fw->size;
Expand All @@ -290,7 +294,7 @@ static int rome_download_firmware(struct hci_dev *hdev,
if (!remain || segsize < MAX_SIZE_PER_TLV_SEGMENT)
config->dnld_mode = ROME_SKIP_EVT_NONE;

ret = rome_tlv_send_segment(hdev, segsize, segment,
ret = qca_tlv_send_segment(hdev, segsize, segment,
config->dnld_mode);
if (ret)
break;
Expand All @@ -317,8 +321,7 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
HCI_VENDOR_PKT, HCI_INIT_TIMEOUT);
if (IS_ERR(skb)) {
err = PTR_ERR(skb);
BT_ERR("%s: Change address command failed (%d)",
hdev->name, err);
bt_dev_err(hdev, "QCA Change address command failed (%d)", err);
return err;
}

Expand All @@ -328,57 +331,65 @@ int qca_set_bdaddr_rome(struct hci_dev *hdev, const bdaddr_t *bdaddr)
}
EXPORT_SYMBOL_GPL(qca_set_bdaddr_rome);

int qca_uart_setup_rome(struct hci_dev *hdev, uint8_t baudrate)
int qca_uart_setup(struct hci_dev *hdev, uint8_t baudrate,
enum qca_btsoc_type soc_type, u32 soc_ver)
{
u32 rome_ver = 0;
struct rome_config config;
int err;
u8 rom_ver;

BT_DBG("%s: ROME setup on UART", hdev->name);
bt_dev_dbg(hdev, "QCA setup on UART");

config.user_baud_rate = baudrate;

/* Get ROME version information */
err = rome_patch_ver_req(hdev, &rome_ver);
if (err < 0 || rome_ver == 0) {
BT_ERR("%s: Failed to get version 0x%x", hdev->name, err);
return err;
}

bt_dev_info(hdev, "ROME controller version 0x%08x", rome_ver);

/* Download rampatch file */
config.type = TLV_TYPE_PATCH;
snprintf(config.fwname, sizeof(config.fwname), "qca/rampatch_%08x.bin",
rome_ver);
err = rome_download_firmware(hdev, &config);
if (soc_type == QCA_WCN3990) {
/* Firmware files to download are based on ROM version.
* ROM version is derived from last two bytes of soc_ver.
*/
rom_ver = ((soc_ver & 0x00000f00) >> 0x04) |
(soc_ver & 0x0000000f);
snprintf(config.fwname, sizeof(config.fwname),
"qca/crbtfw%02x.tlv", rom_ver);
} else {
snprintf(config.fwname, sizeof(config.fwname),
"qca/rampatch_%08x.bin", soc_ver);
}

err = qca_download_firmware(hdev, &config);
if (err < 0) {
BT_ERR("%s: Failed to download patch (%d)", hdev->name, err);
bt_dev_err(hdev, "QCA Failed to download patch (%d)", err);
return err;
}

/* Download NVM configuration */
config.type = TLV_TYPE_NVM;
snprintf(config.fwname, sizeof(config.fwname), "qca/nvm_%08x.bin",
rome_ver);
err = rome_download_firmware(hdev, &config);
if (soc_type == QCA_WCN3990)
snprintf(config.fwname, sizeof(config.fwname),
"qca/crnv%02x.bin", rom_ver);
else
snprintf(config.fwname, sizeof(config.fwname),
"qca/nvm_%08x.bin", soc_ver);

err = qca_download_firmware(hdev, &config);
if (err < 0) {
BT_ERR("%s: Failed to download NVM (%d)", hdev->name, err);
bt_dev_err(hdev, "QCA Failed to download NVM (%d)", err);
return err;
}

/* Perform HCI reset */
err = rome_reset(hdev);
err = qca_send_reset(hdev);
if (err < 0) {
BT_ERR("%s: Failed to run HCI_RESET (%d)", hdev->name, err);
bt_dev_err(hdev, "QCA Failed to run HCI_RESET (%d)", err);
return err;
}

bt_dev_info(hdev, "ROME setup on UART is completed");
bt_dev_info(hdev, "QCA setup on UART is completed");

return 0;
}
EXPORT_SYMBOL_GPL(qca_uart_setup_rome);
EXPORT_SYMBOL_GPL(qca_uart_setup);

MODULE_AUTHOR("Ben Young Tae Kim <ytkim@qca.qualcomm.com>");
MODULE_DESCRIPTION("Bluetooth support for Qualcomm Atheros family ver " VERSION);
Expand Down
Loading

0 comments on commit 6277547

Please sign in to comment.