Commit 596c62b1 authored by John W. Linville's avatar John W. Linville

Merge branch 'for-upstream' of...

Merge branch 'for-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth-next
parents 145babc6 201a5929
...@@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -83,6 +83,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3006) },
{ USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x3008) },
{ USB_DEVICE(0x04CA, 0x300b) },
{ USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE004) },
{ USB_DEVICE(0x0CF3, 0xE005) }, { USB_DEVICE(0x0CF3, 0xE005) },
...@@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -96,6 +97,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x13d3, 0x3402) }, { USB_DEVICE(0x13d3, 0x3402) },
{ USB_DEVICE(0x0cf3, 0x3121) }, { USB_DEVICE(0x0cf3, 0x3121) },
{ USB_DEVICE(0x0cf3, 0xe003) }, { USB_DEVICE(0x0cf3, 0xe003) },
{ USB_DEVICE(0x0489, 0xe05f) },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) }, { USB_DEVICE(0x0489, 0xE02C) },
...@@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -125,6 +127,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
...@@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -138,6 +141,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU22 with sflash firmware */ /* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
......
...@@ -23,8 +23,6 @@ ...@@ -23,8 +23,6 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <linux/ctype.h>
#include <linux/firmware.h>
#define BTM_HEADER_LEN 4 #define BTM_HEADER_LEN 4
#define BTM_UPLD_SIZE 2312 #define BTM_UPLD_SIZE 2312
...@@ -43,8 +41,6 @@ struct btmrvl_thread { ...@@ -43,8 +41,6 @@ struct btmrvl_thread {
struct btmrvl_device { struct btmrvl_device {
void *card; void *card;
struct hci_dev *hcidev; struct hci_dev *hcidev;
struct device *dev;
const char *cal_data;
u8 dev_type; u8 dev_type;
...@@ -90,12 +86,12 @@ struct btmrvl_private { ...@@ -90,12 +86,12 @@ struct btmrvl_private {
#define MRVL_VENDOR_PKT 0xFE #define MRVL_VENDOR_PKT 0xFE
/* Bluetooth commands */ /* Vendor specific Bluetooth commands */
#define BT_CMD_AUTO_SLEEP_MODE 0x23 #define BT_CMD_AUTO_SLEEP_MODE 0xFC23
#define BT_CMD_HOST_SLEEP_CONFIG 0x59 #define BT_CMD_HOST_SLEEP_CONFIG 0xFC59
#define BT_CMD_HOST_SLEEP_ENABLE 0x5A #define BT_CMD_HOST_SLEEP_ENABLE 0xFC5A
#define BT_CMD_MODULE_CFG_REQ 0x5B #define BT_CMD_MODULE_CFG_REQ 0xFC5B
#define BT_CMD_LOAD_CONFIG_DATA 0x61 #define BT_CMD_LOAD_CONFIG_DATA 0xFC61
/* Sub-commands: Module Bringup/Shutdown Request/Response */ /* Sub-commands: Module Bringup/Shutdown Request/Response */
#define MODULE_BRINGUP_REQ 0xF1 #define MODULE_BRINGUP_REQ 0xF1
...@@ -104,6 +100,11 @@ struct btmrvl_private { ...@@ -104,6 +100,11 @@ struct btmrvl_private {
#define MODULE_SHUTDOWN_REQ 0xF2 #define MODULE_SHUTDOWN_REQ 0xF2
/* Vendor specific Bluetooth events */
#define BT_EVENT_AUTO_SLEEP_MODE 0x23
#define BT_EVENT_HOST_SLEEP_CONFIG 0x59
#define BT_EVENT_HOST_SLEEP_ENABLE 0x5A
#define BT_EVENT_MODULE_CFG_REQ 0x5B
#define BT_EVENT_POWER_STATE 0x20 #define BT_EVENT_POWER_STATE 0x20
/* Bluetooth Power States */ /* Bluetooth Power States */
...@@ -111,8 +112,6 @@ struct btmrvl_private { ...@@ -111,8 +112,6 @@ struct btmrvl_private {
#define BT_PS_DISABLE 0x03 #define BT_PS_DISABLE 0x03
#define BT_PS_SLEEP 0x01 #define BT_PS_SLEEP 0x01
#define OGF 0x3F
/* Host Sleep states */ /* Host Sleep states */
#define HS_ACTIVATED 0x01 #define HS_ACTIVATED 0x01
#define HS_DEACTIVATED 0x00 #define HS_DEACTIVATED 0x00
...@@ -121,7 +120,7 @@ struct btmrvl_private { ...@@ -121,7 +120,7 @@ struct btmrvl_private {
#define PS_SLEEP 0x01 #define PS_SLEEP 0x01
#define PS_AWAKE 0x00 #define PS_AWAKE 0x00
#define BT_CMD_DATA_SIZE 32 #define BT_CAL_HDR_LEN 4
#define BT_CAL_DATA_SIZE 28 #define BT_CAL_DATA_SIZE 28
struct btmrvl_event { struct btmrvl_event {
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
**/ **/
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h>
#include <net/bluetooth/bluetooth.h> #include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h> #include <net/bluetooth/hci_core.h>
...@@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -50,12 +50,10 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
if (hdr->evt == HCI_EV_CMD_COMPLETE) { if (hdr->evt == HCI_EV_CMD_COMPLETE) {
struct hci_ev_cmd_complete *ec; struct hci_ev_cmd_complete *ec;
u16 opcode, ocf, ogf; u16 opcode;
ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE);
opcode = __le16_to_cpu(ec->opcode); opcode = __le16_to_cpu(ec->opcode);
ocf = hci_opcode_ocf(opcode);
ogf = hci_opcode_ogf(opcode);
if (priv->btmrvl_dev.sendcmdflag) { if (priv->btmrvl_dev.sendcmdflag) {
priv->btmrvl_dev.sendcmdflag = false; priv->btmrvl_dev.sendcmdflag = false;
...@@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -63,9 +61,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
wake_up_interruptible(&priv->adapter->cmd_wait_q); wake_up_interruptible(&priv->adapter->cmd_wait_q);
} }
if (ogf == OGF) { if (hci_opcode_ogf(opcode) == 0x3F) {
BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x", BT_DBG("vendor event skipped: opcode=%#4.4x", opcode);
ogf, ocf);
kfree_skb(skb); kfree_skb(skb);
return false; return false;
} }
...@@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -89,7 +86,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
} }
switch (event->data[0]) { switch (event->data[0]) {
case BT_CMD_AUTO_SLEEP_MODE: case BT_EVENT_AUTO_SLEEP_MODE:
if (!event->data[2]) { if (!event->data[2]) {
if (event->data[1] == BT_PS_ENABLE) if (event->data[1] == BT_PS_ENABLE)
adapter->psmode = 1; adapter->psmode = 1;
...@@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -102,7 +99,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
} }
break; break;
case BT_CMD_HOST_SLEEP_CONFIG: case BT_EVENT_HOST_SLEEP_CONFIG:
if (!event->data[3]) if (!event->data[3])
BT_DBG("gpio=%x, gap=%x", event->data[1], BT_DBG("gpio=%x, gap=%x", event->data[1],
event->data[2]); event->data[2]);
...@@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -110,7 +107,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
BT_DBG("HSCFG command failed"); BT_DBG("HSCFG command failed");
break; break;
case BT_CMD_HOST_SLEEP_ENABLE: case BT_EVENT_HOST_SLEEP_ENABLE:
if (!event->data[1]) { if (!event->data[1]) {
adapter->hs_state = HS_ACTIVATED; adapter->hs_state = HS_ACTIVATED;
if (adapter->psmode) if (adapter->psmode)
...@@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -121,7 +118,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
} }
break; break;
case BT_CMD_MODULE_CFG_REQ: case BT_EVENT_MODULE_CFG_REQ:
if (priv->btmrvl_dev.sendcmdflag && if (priv->btmrvl_dev.sendcmdflag &&
event->data[1] == MODULE_BRINGUP_REQ) { event->data[1] == MODULE_BRINGUP_REQ) {
BT_DBG("EVENT:%s", BT_DBG("EVENT:%s",
...@@ -166,7 +163,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb) ...@@ -166,7 +163,7 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
} }
EXPORT_SYMBOL_GPL(btmrvl_process_event); EXPORT_SYMBOL_GPL(btmrvl_process_event);
static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 opcode,
const void *param, u8 len) const void *param, u8 len)
{ {
struct sk_buff *skb; struct sk_buff *skb;
...@@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no, ...@@ -179,7 +176,7 @@ static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
} }
hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE); hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no)); hdr->opcode = cpu_to_le16(opcode);
hdr->plen = len; hdr->plen = len;
if (len) if (len)
...@@ -417,127 +414,62 @@ static int btmrvl_open(struct hci_dev *hdev) ...@@ -417,127 +414,62 @@ static int btmrvl_open(struct hci_dev *hdev)
return 0; return 0;
} }
/* static int btmrvl_download_cal_data(struct btmrvl_private *priv,
* This function parses provided calibration data input. It should contain u8 *data, int len)
* hex bytes separated by space or new line character. Here is an example.
* 00 1C 01 37 FF FF FF FF 02 04 7F 01
* CE BA 00 00 00 2D C6 C0 00 00 00 00
* 00 F0 00 00
*/
static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
{ {
const u8 *s = src;
u8 *d = dst;
int ret; int ret;
u8 tmp[3];
tmp[2] = '\0';
while ((s - src) <= len - 2) {
if (isspace(*s)) {
s++;
continue;
}
if (isxdigit(*s)) {
if ((d - dst) >= dst_size) {
BT_ERR("calibration data file too big!!!");
return -EINVAL;
}
memcpy(tmp, s, 2);
ret = kstrtou8(tmp, 16, d++);
if (ret < 0)
return ret;
s += 2;
} else {
return -EINVAL;
}
}
if (d == dst)
return -EINVAL;
return 0;
}
static int btmrvl_load_cal_data(struct btmrvl_private *priv,
u8 *config_data)
{
int i, ret;
u8 data[BT_CMD_DATA_SIZE];
data[0] = 0x00; data[0] = 0x00;
data[1] = 0x00; data[1] = 0x00;
data[2] = 0x00; data[2] = 0x00;
data[3] = BT_CMD_DATA_SIZE - 4; data[3] = len;
/* Swap cal-data bytes. Each four bytes are swapped. Considering 4
* byte SDIO header offset, mapping of input and output bytes will be
* {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
* {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
for (i = 4; i < BT_CMD_DATA_SIZE; i++)
data[i] = config_data[(i / 4) * 8 - 1 - i];
print_hex_dump_bytes("Calibration data: ", print_hex_dump_bytes("Calibration data: ",
DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE); DUMP_PREFIX_OFFSET, data, BT_CAL_HDR_LEN + len);
ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data, ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
BT_CMD_DATA_SIZE); BT_CAL_HDR_LEN + len);
if (ret) if (ret)
BT_ERR("Failed to download caibration data\n"); BT_ERR("Failed to download caibration data\n");
return 0; return 0;
} }
static int static int btmrvl_cal_data_dt(struct btmrvl_private *priv)
btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
{ {
u8 cal_data[BT_CAL_DATA_SIZE]; struct device_node *dt_node;
u8 cal_data[BT_CAL_HDR_LEN + BT_CAL_DATA_SIZE];
const char name[] = "btmrvl_caldata";
const char property[] = "btmrvl,caldata";
int ret; int ret;
ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data)); dt_node = of_find_node_by_name(NULL, name);
if (!dt_node)
return -ENODEV;
ret = of_property_read_u8_array(dt_node, property,
cal_data + BT_CAL_HDR_LEN,
BT_CAL_DATA_SIZE);
if (ret) if (ret)
return ret; return ret;
ret = btmrvl_load_cal_data(priv, cal_data); BT_DBG("Use cal data from device tree");
ret = btmrvl_download_cal_data(priv, cal_data, BT_CAL_DATA_SIZE);
if (ret) { if (ret) {
BT_ERR("Fail to load calibrate data"); BT_ERR("Fail to download calibrate data");
return ret; return ret;
} }
return 0; return 0;
} }
static int btmrvl_cal_data_config(struct btmrvl_private *priv)
{
const struct firmware *cfg;
int ret;
const char *cal_data = priv->btmrvl_dev.cal_data;
if (!cal_data)
return 0;
ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
if (ret < 0) {
BT_DBG("Failed to get %s file, skipping cal data download",
cal_data);
return 0;
}
ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
release_firmware(cfg);
return ret;
}
static int btmrvl_setup(struct hci_dev *hdev) static int btmrvl_setup(struct hci_dev *hdev)
{ {
struct btmrvl_private *priv = hci_get_drvdata(hdev); struct btmrvl_private *priv = hci_get_drvdata(hdev);
btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ); btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
if (btmrvl_cal_data_config(priv)) btmrvl_cal_data_dt(priv);
BT_ERR("Set cal data failed");
priv->btmrvl_dev.psmode = 1; priv->btmrvl_dev.psmode = 1;
btmrvl_enable_ps(priv); btmrvl_enable_ps(priv);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* this warranty disclaimer. * this warranty disclaimer.
**/ **/
#include <linux/firmware.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mmc/sdio_ids.h> #include <linux/mmc/sdio_ids.h>
...@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = { ...@@ -101,7 +102,6 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
.helper = "mrvl/sd8688_helper.bin", .helper = "mrvl/sd8688_helper.bin",
.firmware = "mrvl/sd8688.bin", .firmware = "mrvl/sd8688.bin",
.cal_data = NULL,
.reg = &btmrvl_reg_8688, .reg = &btmrvl_reg_8688,
.sd_blksz_fw_dl = 64, .sd_blksz_fw_dl = 64,
}; };
...@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { ...@@ -109,7 +109,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
.helper = NULL, .helper = NULL,
.firmware = "mrvl/sd8787_uapsta.bin", .firmware = "mrvl/sd8787_uapsta.bin",
.cal_data = NULL,
.reg = &btmrvl_reg_87xx, .reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256, .sd_blksz_fw_dl = 256,
}; };
...@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { ...@@ -117,7 +116,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
.helper = NULL, .helper = NULL,
.firmware = "mrvl/sd8797_uapsta.bin", .firmware = "mrvl/sd8797_uapsta.bin",
.cal_data = "mrvl/sd8797_caldata.conf",
.reg = &btmrvl_reg_87xx, .reg = &btmrvl_reg_87xx,
.sd_blksz_fw_dl = 256, .sd_blksz_fw_dl = 256,
}; };
...@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { ...@@ -125,7 +123,6 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
.helper = NULL, .helper = NULL,
.firmware = "mrvl/sd8897_uapsta.bin", .firmware = "mrvl/sd8897_uapsta.bin",
.cal_data = NULL,
.reg = &btmrvl_reg_88xx, .reg = &btmrvl_reg_88xx,
.sd_blksz_fw_dl = 256, .sd_blksz_fw_dl = 256,
}; };
...@@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func, ...@@ -1007,7 +1004,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
struct btmrvl_sdio_device *data = (void *) id->driver_data; struct btmrvl_sdio_device *data = (void *) id->driver_data;
card->helper = data->helper; card->helper = data->helper;
card->firmware = data->firmware; card->firmware = data->firmware;
card->cal_data = data->cal_data;
card->reg = data->reg; card->reg = data->reg;
card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
} }
...@@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func, ...@@ -1036,8 +1032,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
} }
card->priv = priv; card->priv = priv;
priv->btmrvl_dev.dev = &card->func->dev;
priv->btmrvl_dev.cal_data = card->cal_data;
/* Initialize the interface specific function pointers */ /* Initialize the interface specific function pointers */
priv->hw_host_to_card = btmrvl_sdio_host_to_card; priv->hw_host_to_card = btmrvl_sdio_host_to_card;
...@@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin"); ...@@ -1220,5 +1214,4 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
MODULE_FIRMWARE("mrvl/sd8688.bin"); MODULE_FIRMWARE("mrvl/sd8688.bin");
MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
...@@ -85,7 +85,6 @@ struct btmrvl_sdio_card { ...@@ -85,7 +85,6 @@ struct btmrvl_sdio_card {
u32 ioport; u32 ioport;
const char *helper; const char *helper;
const char *firmware; const char *firmware;
const char *cal_data;
const struct btmrvl_sdio_card_reg *reg; const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl; u16 sd_blksz_fw_dl;
u8 rx_unit; u8 rx_unit;
...@@ -95,7 +94,6 @@ struct btmrvl_sdio_card { ...@@ -95,7 +94,6 @@ struct btmrvl_sdio_card {
struct btmrvl_sdio_device { struct btmrvl_sdio_device {
const char *helper; const char *helper;
const char *firmware; const char *firmware;
const char *cal_data;
const struct btmrvl_sdio_card_reg *reg; const struct btmrvl_sdio_card_reg *reg;
u16 sd_blksz_fw_dl; u16 sd_blksz_fw_dl;
}; };
......
...@@ -150,6 +150,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -150,6 +150,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
...@@ -163,6 +164,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -163,6 +164,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3121), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe003), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
/* Atheros AR5BBU12 with sflash firmware */ /* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
...@@ -223,6 +225,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -223,6 +225,7 @@ static const struct usb_device_id blacklist_table[] = {
/* Intel Bluetooth device */ /* Intel Bluetooth device */
{ USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL }, { USB_DEVICE(0x8087, 0x07dc), .driver_info = BTUSB_INTEL },
{ USB_DEVICE(0x8087, 0x0a2a), .driver_info = BTUSB_INTEL },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -1435,8 +1438,10 @@ static int btusb_probe(struct usb_interface *intf, ...@@ -1435,8 +1438,10 @@ static int btusb_probe(struct usb_interface *intf,
if (id->driver_info & BTUSB_BCM92035) if (id->driver_info & BTUSB_BCM92035)
hdev->setup = btusb_setup_bcm92035; hdev->setup = btusb_setup_bcm92035;
if (id->driver_info & BTUSB_INTEL) if (id->driver_info & BTUSB_INTEL) {
usb_enable_autosuspend(data->udev);
hdev->setup = btusb_setup_intel; hdev->setup = btusb_setup_intel;
}
/* Interface numbers are hardcoded in the specification */ /* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1); data->isoc = usb_ifnum_to_if(data->udev, 1);
......
...@@ -1275,15 +1275,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) ...@@ -1275,15 +1275,17 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt)
hci_setup_link_policy(req); hci_setup_link_policy(req);
if (lmp_le_capable(hdev)) { if (lmp_le_capable(hdev)) {
/* If the controller has a public BD_ADDR, then by if (test_bit(HCI_SETUP, &hdev->dev_flags)) {
* default use that one. If this is a LE only /* If the controller has a public BD_ADDR, then
* controller without one, default to the random * by default use that one. If this is a LE only
* address. * controller without a public address, default
*/ * to the random address.
if (bacmp(&hdev->bdaddr, BDADDR_ANY)) */
hdev->own_addr_type = ADDR_LE_DEV_PUBLIC; if (bacmp(&hdev->bdaddr, BDADDR_ANY))
else hdev->own_addr_type = ADDR_LE_DEV_PUBLIC;
hdev->own_addr_type = ADDR_LE_DEV_RANDOM; else
hdev->own_addr_type = ADDR_LE_DEV_RANDOM;
}
hci_set_le_support(req); hci_set_le_support(req);
} }
......
...@@ -486,7 +486,10 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, ...@@ -486,7 +486,10 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev,
BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
if (!rp->status) if (rp->status)
return;
if (test_bit(HCI_SETUP, &hdev->dev_flags))
memcpy(hdev->commands, rp->commands, sizeof(hdev->commands)); memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
} }
...@@ -538,12 +541,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, ...@@ -538,12 +541,6 @@ static void hci_cc_read_local_features(struct hci_dev *hdev,
if (hdev->features[0][5] & LMP_EDR_3S_ESCO) if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5); hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
hdev->features[0][0], hdev->features[0][1],
hdev->features[0][2], hdev->features[0][3],
hdev->features[0][4], hdev->features[0][5],
hdev->features[0][6], hdev->features[0][7]);
} }
static void hci_cc_read_local_ext_features(struct hci_dev *hdev, static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
...@@ -1782,7 +1779,9 @@ static u8 hci_to_mgmt_reason(u8 err) ...@@ -1782,7 +1779,9 @@ static u8 hci_to_mgmt_reason(u8 err)
static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_ev_disconn_complete *ev = (void *) skb->data; struct hci_ev_disconn_complete *ev = (void *) skb->data;
u8 reason = hci_to_mgmt_reason(ev->reason);
struct hci_conn *conn; struct hci_conn *conn;
u8 type;
BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
...@@ -1792,43 +1791,38 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -1792,43 +1791,38 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
if (!conn) if (!conn)
goto unlock; goto unlock;
if (ev->status == 0) if (ev->status) {
conn->state = BT_CLOSED; mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, ev->status);
goto unlock;
}
if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) && conn->state = BT_CLOSED;
(conn->type == ACL_LINK || conn->type == LE_LINK)) {
if (ev->status) {
mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
conn->dst_type, ev->status);
} else {
u8 reason = hci_to_mgmt_reason(ev->reason);
mgmt_device_disconnected(hdev, &conn->dst, conn->type, if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
conn->dst_type, reason); mgmt_device_disconnected(hdev, &conn->dst, conn->type,
} conn->dst_type, reason);
}
if (ev->status == 0) { if (conn->type == ACL_LINK && conn->flush_key)
u8 type = conn->type; hci_remove_link_key(hdev, &conn->dst);
if (type == ACL_LINK && conn->flush_key) type = conn->type;
hci_remove_link_key(hdev, &conn->dst);
hci_proto_disconn_cfm(conn, ev->reason);
hci_conn_del(conn);
/* Re-enable advertising if necessary, since it might hci_proto_disconn_cfm(conn, ev->reason);
* have been disabled by the connection. From the hci_conn_del(conn);
* HCI_LE_Set_Advertise_Enable command description in
* the core specification (v4.0): /* Re-enable advertising if necessary, since it might
* "The Controller shall continue advertising until the Host * have been disabled by the connection. From the
* issues an LE_Set_Advertise_Enable command with * HCI_LE_Set_Advertise_Enable command description in
* Advertising_Enable set to 0x00 (Advertising is disabled) * the core specification (v4.0):
* or until a connection is created or until the Advertising * "The Controller shall continue advertising until the Host
* is timed out due to Directed Advertising." * issues an LE_Set_Advertise_Enable command with
*/ * Advertising_Enable set to 0x00 (Advertising is disabled)
if (type == LE_LINK) * or until a connection is created or until the Advertising
mgmt_reenable_advertising(hdev); * is timed out due to Directed Advertising."
} */
if (type == LE_LINK)
mgmt_reenable_advertising(hdev);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
......
...@@ -1264,7 +1264,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -1264,7 +1264,7 @@ static int set_discoverable(struct sock *sk, struct hci_dev *hdev, void *data,
if (cp->val == 0x02) { if (cp->val == 0x02) {
/* Limited discoverable mode */ /* Limited discoverable mode */
hci_cp.num_iac = 2; hci_cp.num_iac = min_t(u8, hdev->num_iac, 2);
hci_cp.iac_lap[0] = 0x00; /* LIAC */ hci_cp.iac_lap[0] = 0x00; /* LIAC */
hci_cp.iac_lap[1] = 0x8b; hci_cp.iac_lap[1] = 0x8b;
hci_cp.iac_lap[2] = 0x9e; hci_cp.iac_lap[2] = 0x9e;
...@@ -4595,6 +4595,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -4595,6 +4595,9 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
struct mgmt_ev_device_disconnected ev; struct mgmt_ev_device_disconnected ev;
struct sock *sk = NULL; struct sock *sk = NULL;
if (link_type != ACL_LINK && link_type != LE_LINK)
return;
mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk); mgmt_pending_foreach(MGMT_OP_DISCONNECT, hdev, disconnect_rsp, &sk);
bacpy(&ev.addr.bdaddr, bdaddr); bacpy(&ev.addr.bdaddr, bdaddr);
...@@ -4613,6 +4616,8 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -4613,6 +4616,8 @@ void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr,
void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
u8 link_type, u8 addr_type, u8 status) u8 link_type, u8 addr_type, u8 status)
{ {
u8 bdaddr_type = link_to_bdaddr(link_type, addr_type);
struct mgmt_cp_disconnect *cp;
struct mgmt_rp_disconnect rp; struct mgmt_rp_disconnect rp;
struct pending_cmd *cmd; struct pending_cmd *cmd;
...@@ -4623,8 +4628,16 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, ...@@ -4623,8 +4628,16 @@ void mgmt_disconnect_failed(struct hci_dev *hdev, bdaddr_t *bdaddr,
if (!cmd) if (!cmd)
return; return;
cp = cmd->param;
if (bacmp(bdaddr, &cp->addr.bdaddr))
return;
if (cp->addr.type != bdaddr_type)
return;
bacpy(&rp.addr.bdaddr, bdaddr); bacpy(&rp.addr.bdaddr, bdaddr);
rp.addr.type = link_to_bdaddr(link_type, addr_type); rp.addr.type = bdaddr_type;
cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT, cmd_complete(cmd->sk, cmd->index, MGMT_OP_DISCONNECT,
mgmt_status(status), &rp, sizeof(rp)); mgmt_status(status), &rp, sizeof(rp));
......
...@@ -53,8 +53,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) ...@@ -53,8 +53,7 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
{ {
struct blkcipher_desc desc; struct blkcipher_desc desc;
struct scatterlist sg; struct scatterlist sg;
int err, iv_len; int err;
unsigned char iv[128];
if (tfm == NULL) { if (tfm == NULL) {
BT_ERR("tfm %p", tfm); BT_ERR("tfm %p", tfm);
...@@ -72,12 +71,6 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r) ...@@ -72,12 +71,6 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
sg_init_one(&sg, r, 16); sg_init_one(&sg, r, 16);
iv_len = crypto_blkcipher_ivsize(tfm);
if (iv_len) {
memset(&iv, 0xff, iv_len);
crypto_blkcipher_set_iv(tfm, iv, iv_len);
}
err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16); err = crypto_blkcipher_encrypt(&desc, &sg, &sg, 16);
if (err) if (err)
BT_ERR("Encrypt data error %d", err); BT_ERR("Encrypt data error %d", err);
...@@ -143,13 +136,6 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16], ...@@ -143,13 +136,6 @@ static int smp_s1(struct crypto_blkcipher *tfm, u8 k[16], u8 r1[16],
return err; return err;
} }
static int smp_rand(u8 *buf)
{
get_random_bytes(buf, 16);
return 0;
}
static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code, static struct sk_buff *smp_build_cmd(struct l2cap_conn *conn, u8 code,
u16 dlen, void *data) u16 dlen, void *data)
{ {
...@@ -257,11 +243,11 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size) ...@@ -257,11 +243,11 @@ static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
return 0; return 0;
} }
static void smp_failure(struct l2cap_conn *conn, u8 reason, u8 send) static void smp_failure(struct l2cap_conn *conn, u8 reason)
{ {
struct hci_conn *hcon = conn->hcon; struct hci_conn *hcon = conn->hcon;
if (send) if (reason)
smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason),
&reason); &reason);
...@@ -406,7 +392,7 @@ static void confirm_work(struct work_struct *work) ...@@ -406,7 +392,7 @@ static void confirm_work(struct work_struct *work)
return; return;
error: error:
smp_failure(conn, reason, 1); smp_failure(conn, reason);
} }
static void random_work(struct work_struct *work) static void random_work(struct work_struct *work)
...@@ -490,7 +476,7 @@ static void random_work(struct work_struct *work) ...@@ -490,7 +476,7 @@ static void random_work(struct work_struct *work)
return; return;
error: error:
smp_failure(conn, reason, 1); smp_failure(conn, reason);
} }
static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) static struct smp_chan *smp_chan_create(struct l2cap_conn *conn)
...@@ -555,10 +541,10 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) ...@@ -555,10 +541,10 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey)
break; break;
case MGMT_OP_USER_PASSKEY_NEG_REPLY: case MGMT_OP_USER_PASSKEY_NEG_REPLY:
case MGMT_OP_USER_CONFIRM_NEG_REPLY: case MGMT_OP_USER_CONFIRM_NEG_REPLY:
smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
return 0; return 0;
default: default:
smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED, 1); smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED);
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -606,9 +592,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -606,9 +592,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb)
if (check_enc_key_size(conn, key_size)) if (check_enc_key_size(conn, key_size))
return SMP_ENC_KEY_SIZE; return SMP_ENC_KEY_SIZE;
ret = smp_rand(smp->prnd); get_random_bytes(smp->prnd, sizeof(smp->prnd));
if (ret)
return SMP_UNSPECIFIED;
smp->prsp[0] = SMP_CMD_PAIRING_RSP; smp->prsp[0] = SMP_CMD_PAIRING_RSP;
memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); memcpy(&smp->prsp[1], &rsp, sizeof(rsp));
...@@ -644,9 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -644,9 +628,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb)
if (check_enc_key_size(conn, key_size)) if (check_enc_key_size(conn, key_size))
return SMP_ENC_KEY_SIZE; return SMP_ENC_KEY_SIZE;
ret = smp_rand(smp->prnd); get_random_bytes(smp->prnd, sizeof(smp->prnd));
if (ret)
return SMP_UNSPECIFIED;
smp->prsp[0] = SMP_CMD_PAIRING_RSP; smp->prsp[0] = SMP_CMD_PAIRING_RSP;
memcpy(&smp->prsp[1], rsp, sizeof(*rsp)); memcpy(&smp->prsp[1], rsp, sizeof(*rsp));
...@@ -895,7 +877,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -895,7 +877,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
break; break;
case SMP_CMD_PAIRING_FAIL: case SMP_CMD_PAIRING_FAIL:
smp_failure(conn, skb->data[0], 0); smp_failure(conn, 0);
reason = 0; reason = 0;
err = -EPERM; err = -EPERM;
break; break;
...@@ -941,7 +923,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) ...@@ -941,7 +923,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
done: done:
if (reason) if (reason)
smp_failure(conn, reason, 1); smp_failure(conn, reason);
kfree_skb(skb); kfree_skb(skb);
return err; return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment