aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r--drivers/bluetooth/Makefile2
-rw-r--r--drivers/bluetooth/btmrvl_drv.h12
-rw-r--r--drivers/bluetooth/btmrvl_main.c269
-rw-r--r--drivers/bluetooth/btmrvl_sdio.c15
-rw-r--r--drivers/bluetooth/btmrvl_sdio.h2
-rw-r--r--drivers/bluetooth/hci_vhci.c170
6 files changed, 319 insertions, 151 deletions
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile
index 4afae20df512..9fe8a875a827 100644
--- a/drivers/bluetooth/Makefile
+++ b/drivers/bluetooth/Makefile
@@ -30,3 +30,5 @@ hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
30hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o 30hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o
31hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o 31hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o
32hci_uart-objs := $(hci_uart-y) 32hci_uart-objs := $(hci_uart-y)
33
34ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/bluetooth/btmrvl_drv.h b/drivers/bluetooth/btmrvl_drv.h
index 27068d149380..f9d183387f45 100644
--- a/drivers/bluetooth/btmrvl_drv.h
+++ b/drivers/bluetooth/btmrvl_drv.h
@@ -23,6 +23,8 @@
23#include <linux/bitops.h> 23#include <linux/bitops.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <net/bluetooth/bluetooth.h> 25#include <net/bluetooth/bluetooth.h>
26#include <linux/ctype.h>
27#include <linux/firmware.h>
26 28
27#define BTM_HEADER_LEN 4 29#define BTM_HEADER_LEN 4
28#define BTM_UPLD_SIZE 2312 30#define BTM_UPLD_SIZE 2312
@@ -41,6 +43,8 @@ struct btmrvl_thread {
41struct btmrvl_device { 43struct btmrvl_device {
42 void *card; 44 void *card;
43 struct hci_dev *hcidev; 45 struct hci_dev *hcidev;
46 struct device *dev;
47 const char *cal_data;
44 48
45 u8 dev_type; 49 u8 dev_type;
46 50
@@ -91,6 +95,7 @@ struct btmrvl_private {
91#define BT_CMD_HOST_SLEEP_CONFIG 0x59 95#define BT_CMD_HOST_SLEEP_CONFIG 0x59
92#define BT_CMD_HOST_SLEEP_ENABLE 0x5A 96#define BT_CMD_HOST_SLEEP_ENABLE 0x5A
93#define BT_CMD_MODULE_CFG_REQ 0x5B 97#define BT_CMD_MODULE_CFG_REQ 0x5B
98#define BT_CMD_LOAD_CONFIG_DATA 0x61
94 99
95/* Sub-commands: Module Bringup/Shutdown Request/Response */ 100/* Sub-commands: Module Bringup/Shutdown Request/Response */
96#define MODULE_BRINGUP_REQ 0xF1 101#define MODULE_BRINGUP_REQ 0xF1
@@ -116,11 +121,8 @@ struct btmrvl_private {
116#define PS_SLEEP 0x01 121#define PS_SLEEP 0x01
117#define PS_AWAKE 0x00 122#define PS_AWAKE 0x00
118 123
119struct btmrvl_cmd { 124#define BT_CMD_DATA_SIZE 32
120 __le16 ocf_ogf; 125#define BT_CAL_DATA_SIZE 28
121 u8 length;
122 u8 data[4];
123} __packed;
124 126
125struct btmrvl_event { 127struct btmrvl_event {
126 u8 ec; /* event counter */ 128 u8 ec; /* event counter */
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c
index 9a9f51875df5..6e7bd4e4adbb 100644
--- a/drivers/bluetooth/btmrvl_main.c
+++ b/drivers/bluetooth/btmrvl_main.c
@@ -57,8 +57,7 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb)
57 ocf = hci_opcode_ocf(opcode); 57 ocf = hci_opcode_ocf(opcode);
58 ogf = hci_opcode_ogf(opcode); 58 ogf = hci_opcode_ogf(opcode);
59 59
60 if (ocf == BT_CMD_MODULE_CFG_REQ && 60 if (priv->btmrvl_dev.sendcmdflag) {
61 priv->btmrvl_dev.sendcmdflag) {
62 priv->btmrvl_dev.sendcmdflag = false; 61 priv->btmrvl_dev.sendcmdflag = false;
63 priv->adapter->cmd_complete = true; 62 priv->adapter->cmd_complete = true;
64 wake_up_interruptible(&priv->adapter->cmd_wait_q); 63 wake_up_interruptible(&priv->adapter->cmd_wait_q);
@@ -116,7 +115,6 @@ int btmrvl_process_event(struct btmrvl_private *priv, struct sk_buff *skb)
116 adapter->hs_state = HS_ACTIVATED; 115 adapter->hs_state = HS_ACTIVATED;
117 if (adapter->psmode) 116 if (adapter->psmode)
118 adapter->ps_state = PS_SLEEP; 117 adapter->ps_state = PS_SLEEP;
119 wake_up_interruptible(&adapter->cmd_wait_q);
120 BT_DBG("HS ACTIVATED!"); 118 BT_DBG("HS ACTIVATED!");
121 } else { 119 } else {
122 BT_DBG("HS Enable failed"); 120 BT_DBG("HS Enable failed");
@@ -168,22 +166,24 @@ exit:
168} 166}
169EXPORT_SYMBOL_GPL(btmrvl_process_event); 167EXPORT_SYMBOL_GPL(btmrvl_process_event);
170 168
171int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd) 169static int btmrvl_send_sync_cmd(struct btmrvl_private *priv, u16 cmd_no,
170 const void *param, u8 len)
172{ 171{
173 struct sk_buff *skb; 172 struct sk_buff *skb;
174 struct btmrvl_cmd *cmd; 173 struct hci_command_hdr *hdr;
175 int ret = 0;
176 174
177 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC); 175 skb = bt_skb_alloc(HCI_COMMAND_HDR_SIZE + len, GFP_ATOMIC);
178 if (skb == NULL) { 176 if (skb == NULL) {
179 BT_ERR("No free skb"); 177 BT_ERR("No free skb");
180 return -ENOMEM; 178 return -ENOMEM;
181 } 179 }
182 180
183 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd)); 181 hdr = (struct hci_command_hdr *)skb_put(skb, HCI_COMMAND_HDR_SIZE);
184 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_MODULE_CFG_REQ)); 182 hdr->opcode = cpu_to_le16(hci_opcode_pack(OGF, cmd_no));
185 cmd->length = 1; 183 hdr->plen = len;
186 cmd->data[0] = subcmd; 184
185 if (len)
186 memcpy(skb_put(skb, len), param, len);
187 187
188 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; 188 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
189 189
@@ -194,19 +194,23 @@ int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
194 194
195 priv->adapter->cmd_complete = false; 195 priv->adapter->cmd_complete = false;
196 196
197 BT_DBG("Queue module cfg Command");
198
199 wake_up_interruptible(&priv->main_thread.wait_q); 197 wake_up_interruptible(&priv->main_thread.wait_q);
200 198
201 if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, 199 if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q,
202 priv->adapter->cmd_complete, 200 priv->adapter->cmd_complete,
203 msecs_to_jiffies(WAIT_UNTIL_CMD_RESP))) { 201 msecs_to_jiffies(WAIT_UNTIL_CMD_RESP)))
204 ret = -ETIMEDOUT; 202 return -ETIMEDOUT;
205 BT_ERR("module_cfg_cmd(%x): timeout: %d",
206 subcmd, priv->btmrvl_dev.sendcmdflag);
207 }
208 203
209 BT_DBG("module cfg Command done"); 204 return 0;
205}
206
207int btmrvl_send_module_cfg_cmd(struct btmrvl_private *priv, int subcmd)
208{
209 int ret;
210
211 ret = btmrvl_send_sync_cmd(priv, BT_CMD_MODULE_CFG_REQ, &subcmd, 1);
212 if (ret)
213 BT_ERR("module_cfg_cmd(%x) failed\n", subcmd);
210 214
211 return ret; 215 return ret;
212} 216}
@@ -214,61 +218,36 @@ EXPORT_SYMBOL_GPL(btmrvl_send_module_cfg_cmd);
214 218
215int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv) 219int btmrvl_send_hscfg_cmd(struct btmrvl_private *priv)
216{ 220{
217 struct sk_buff *skb; 221 int ret;
218 struct btmrvl_cmd *cmd; 222 u8 param[2];
219
220 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
221 if (!skb) {
222 BT_ERR("No free skb");
223 return -ENOMEM;
224 }
225
226 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
227 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
228 BT_CMD_HOST_SLEEP_CONFIG));
229 cmd->length = 2;
230 cmd->data[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
231 cmd->data[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
232 223
233 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT; 224 param[0] = (priv->btmrvl_dev.gpio_gap & 0xff00) >> 8;
225 param[1] = (u8) (priv->btmrvl_dev.gpio_gap & 0x00ff);
234 226
235 skb->dev = (void *) priv->btmrvl_dev.hcidev; 227 BT_DBG("Sending HSCFG Command, gpio=0x%x, gap=0x%x",
236 skb_queue_head(&priv->adapter->tx_queue, skb); 228 param[0], param[1]);
237 229
238 BT_DBG("Queue HSCFG Command, gpio=0x%x, gap=0x%x", cmd->data[0], 230 ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_CONFIG, param, 2);
239 cmd->data[1]); 231 if (ret)
232 BT_ERR("HSCFG command failed\n");
240 233
241 return 0; 234 return ret;
242} 235}
243EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd); 236EXPORT_SYMBOL_GPL(btmrvl_send_hscfg_cmd);
244 237
245int btmrvl_enable_ps(struct btmrvl_private *priv) 238int btmrvl_enable_ps(struct btmrvl_private *priv)
246{ 239{
247 struct sk_buff *skb; 240 int ret;
248 struct btmrvl_cmd *cmd; 241 u8 param;
249
250 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
251 if (skb == NULL) {
252 BT_ERR("No free skb");
253 return -ENOMEM;
254 }
255
256 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
257 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF,
258 BT_CMD_AUTO_SLEEP_MODE));
259 cmd->length = 1;
260 242
261 if (priv->btmrvl_dev.psmode) 243 if (priv->btmrvl_dev.psmode)
262 cmd->data[0] = BT_PS_ENABLE; 244 param = BT_PS_ENABLE;
263 else 245 else
264 cmd->data[0] = BT_PS_DISABLE; 246 param = BT_PS_DISABLE;
265
266 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
267 247
268 skb->dev = (void *) priv->btmrvl_dev.hcidev; 248 ret = btmrvl_send_sync_cmd(priv, BT_CMD_AUTO_SLEEP_MODE, &param, 1);
269 skb_queue_head(&priv->adapter->tx_queue, skb); 249 if (ret)
270 250 BT_ERR("PSMODE command failed\n");
271 BT_DBG("Queue PSMODE Command:%d", cmd->data[0]);
272 251
273 return 0; 252 return 0;
274} 253}
@@ -276,37 +255,11 @@ EXPORT_SYMBOL_GPL(btmrvl_enable_ps);
276 255
277int btmrvl_enable_hs(struct btmrvl_private *priv) 256int btmrvl_enable_hs(struct btmrvl_private *priv)
278{ 257{
279 struct sk_buff *skb; 258 int ret;
280 struct btmrvl_cmd *cmd;
281 int ret = 0;
282
283 skb = bt_skb_alloc(sizeof(*cmd), GFP_ATOMIC);
284 if (skb == NULL) {
285 BT_ERR("No free skb");
286 return -ENOMEM;
287 }
288
289 cmd = (struct btmrvl_cmd *) skb_put(skb, sizeof(*cmd));
290 cmd->ocf_ogf = cpu_to_le16(hci_opcode_pack(OGF, BT_CMD_HOST_SLEEP_ENABLE));
291 cmd->length = 0;
292
293 bt_cb(skb)->pkt_type = MRVL_VENDOR_PKT;
294
295 skb->dev = (void *) priv->btmrvl_dev.hcidev;
296 skb_queue_head(&priv->adapter->tx_queue, skb);
297
298 BT_DBG("Queue hs enable Command");
299
300 wake_up_interruptible(&priv->main_thread.wait_q);
301 259
302 if (!wait_event_interruptible_timeout(priv->adapter->cmd_wait_q, 260 ret = btmrvl_send_sync_cmd(priv, BT_CMD_HOST_SLEEP_ENABLE, NULL, 0);
303 priv->adapter->hs_state, 261 if (ret)
304 msecs_to_jiffies(WAIT_UNTIL_HS_STATE_CHANGED))) { 262 BT_ERR("Host sleep enable command failed\n");
305 ret = -ETIMEDOUT;
306 BT_ERR("timeout: %d, %d,%d", priv->adapter->hs_state,
307 priv->adapter->ps_state,
308 priv->adapter->wakeup_tries);
309 }
310 263
311 return ret; 264 return ret;
312} 265}
@@ -480,6 +433,137 @@ static int btmrvl_open(struct hci_dev *hdev)
480} 433}
481 434
482/* 435/*
436 * This function parses provided calibration data input. It should contain
437 * hex bytes separated by space or new line character. Here is an example.
438 * 00 1C 01 37 FF FF FF FF 02 04 7F 01
439 * CE BA 00 00 00 2D C6 C0 00 00 00 00
440 * 00 F0 00 00
441 */
442static int btmrvl_parse_cal_cfg(const u8 *src, u32 len, u8 *dst, u32 dst_size)
443{
444 const u8 *s = src;
445 u8 *d = dst;
446 int ret;
447 u8 tmp[3];
448
449 tmp[2] = '\0';
450 while ((s - src) <= len - 2) {
451 if (isspace(*s)) {
452 s++;
453 continue;
454 }
455
456 if (isxdigit(*s)) {
457 if ((d - dst) >= dst_size) {
458 BT_ERR("calibration data file too big!!!");
459 return -EINVAL;
460 }
461
462 memcpy(tmp, s, 2);
463
464 ret = kstrtou8(tmp, 16, d++);
465 if (ret < 0)
466 return ret;
467
468 s += 2;
469 } else {
470 return -EINVAL;
471 }
472 }
473 if (d == dst)
474 return -EINVAL;
475
476 return 0;
477}
478
479static int btmrvl_load_cal_data(struct btmrvl_private *priv,
480 u8 *config_data)
481{
482 int i, ret;
483 u8 data[BT_CMD_DATA_SIZE];
484
485 data[0] = 0x00;
486 data[1] = 0x00;
487 data[2] = 0x00;
488 data[3] = BT_CMD_DATA_SIZE - 4;
489
490 /* Swap cal-data bytes. Each four bytes are swapped. Considering 4
491 * byte SDIO header offset, mapping of input and output bytes will be
492 * {3, 2, 1, 0} -> {0+4, 1+4, 2+4, 3+4},
493 * {7, 6, 5, 4} -> {4+4, 5+4, 6+4, 7+4} */
494 for (i = 4; i < BT_CMD_DATA_SIZE; i++)
495 data[i] = config_data[(i / 4) * 8 - 1 - i];
496
497 print_hex_dump_bytes("Calibration data: ",
498 DUMP_PREFIX_OFFSET, data, BT_CMD_DATA_SIZE);
499
500 ret = btmrvl_send_sync_cmd(priv, BT_CMD_LOAD_CONFIG_DATA, data,
501 BT_CMD_DATA_SIZE);
502 if (ret)
503 BT_ERR("Failed to download caibration data\n");
504
505 return 0;
506}
507
508static int
509btmrvl_process_cal_cfg(struct btmrvl_private *priv, u8 *data, u32 size)
510{
511 u8 cal_data[BT_CAL_DATA_SIZE];
512 int ret;
513
514 ret = btmrvl_parse_cal_cfg(data, size, cal_data, sizeof(cal_data));
515 if (ret)
516 return ret;
517
518 ret = btmrvl_load_cal_data(priv, cal_data);
519 if (ret) {
520 BT_ERR("Fail to load calibrate data");
521 return ret;
522 }
523
524 return 0;
525}
526
527static int btmrvl_cal_data_config(struct btmrvl_private *priv)
528{
529 const struct firmware *cfg;
530 int ret;
531 const char *cal_data = priv->btmrvl_dev.cal_data;
532
533 if (!cal_data)
534 return 0;
535
536 ret = request_firmware(&cfg, cal_data, priv->btmrvl_dev.dev);
537 if (ret < 0) {
538 BT_DBG("Failed to get %s file, skipping cal data download",
539 cal_data);
540 return 0;
541 }
542
543 ret = btmrvl_process_cal_cfg(priv, (u8 *)cfg->data, cfg->size);
544 release_firmware(cfg);
545 return ret;
546}
547
548static int btmrvl_setup(struct hci_dev *hdev)
549{
550 struct btmrvl_private *priv = hci_get_drvdata(hdev);
551
552 btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
553
554 if (btmrvl_cal_data_config(priv))
555 BT_ERR("Set cal data failed");
556
557 priv->btmrvl_dev.psmode = 1;
558 btmrvl_enable_ps(priv);
559
560 priv->btmrvl_dev.gpio_gap = 0xffff;
561 btmrvl_send_hscfg_cmd(priv);
562
563 return 0;
564}
565
566/*
483 * This function handles the event generated by firmware, rx data 567 * This function handles the event generated by firmware, rx data
484 * received from firmware, and tx data sent from kernel. 568 * received from firmware, and tx data sent from kernel.
485 */ 569 */
@@ -572,8 +656,7 @@ int btmrvl_register_hdev(struct btmrvl_private *priv)
572 hdev->flush = btmrvl_flush; 656 hdev->flush = btmrvl_flush;
573 hdev->send = btmrvl_send_frame; 657 hdev->send = btmrvl_send_frame;
574 hdev->ioctl = btmrvl_ioctl; 658 hdev->ioctl = btmrvl_ioctl;
575 659 hdev->setup = btmrvl_setup;
576 btmrvl_send_module_cfg_cmd(priv, MODULE_BRINGUP_REQ);
577 660
578 hdev->dev_type = priv->btmrvl_dev.dev_type; 661 hdev->dev_type = priv->btmrvl_dev.dev_type;
579 662
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c
index 00da6df9f71e..332475e400cf 100644
--- a/drivers/bluetooth/btmrvl_sdio.c
+++ b/drivers/bluetooth/btmrvl_sdio.c
@@ -18,7 +18,6 @@
18 * this warranty disclaimer. 18 * this warranty disclaimer.
19 **/ 19 **/
20 20
21#include <linux/firmware.h>
22#include <linux/slab.h> 21#include <linux/slab.h>
23 22
24#include <linux/mmc/sdio_ids.h> 23#include <linux/mmc/sdio_ids.h>
@@ -102,6 +101,7 @@ static const struct btmrvl_sdio_card_reg btmrvl_reg_88xx = {
102static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = { 101static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
103 .helper = "mrvl/sd8688_helper.bin", 102 .helper = "mrvl/sd8688_helper.bin",
104 .firmware = "mrvl/sd8688.bin", 103 .firmware = "mrvl/sd8688.bin",
104 .cal_data = NULL,
105 .reg = &btmrvl_reg_8688, 105 .reg = &btmrvl_reg_8688,
106 .sd_blksz_fw_dl = 64, 106 .sd_blksz_fw_dl = 64,
107}; 107};
@@ -109,6 +109,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8688 = {
109static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = { 109static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
110 .helper = NULL, 110 .helper = NULL,
111 .firmware = "mrvl/sd8787_uapsta.bin", 111 .firmware = "mrvl/sd8787_uapsta.bin",
112 .cal_data = NULL,
112 .reg = &btmrvl_reg_87xx, 113 .reg = &btmrvl_reg_87xx,
113 .sd_blksz_fw_dl = 256, 114 .sd_blksz_fw_dl = 256,
114}; 115};
@@ -116,6 +117,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
116static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = { 117static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
117 .helper = NULL, 118 .helper = NULL,
118 .firmware = "mrvl/sd8797_uapsta.bin", 119 .firmware = "mrvl/sd8797_uapsta.bin",
120 .cal_data = "mrvl/sd8797_caldata.conf",
119 .reg = &btmrvl_reg_87xx, 121 .reg = &btmrvl_reg_87xx,
120 .sd_blksz_fw_dl = 256, 122 .sd_blksz_fw_dl = 256,
121}; 123};
@@ -123,6 +125,7 @@ static const struct btmrvl_sdio_device btmrvl_sdio_sd8797 = {
123static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = { 125static const struct btmrvl_sdio_device btmrvl_sdio_sd8897 = {
124 .helper = NULL, 126 .helper = NULL,
125 .firmware = "mrvl/sd8897_uapsta.bin", 127 .firmware = "mrvl/sd8897_uapsta.bin",
128 .cal_data = NULL,
126 .reg = &btmrvl_reg_88xx, 129 .reg = &btmrvl_reg_88xx,
127 .sd_blksz_fw_dl = 256, 130 .sd_blksz_fw_dl = 256,
128}; 131};
@@ -1006,6 +1009,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
1006 struct btmrvl_sdio_device *data = (void *) id->driver_data; 1009 struct btmrvl_sdio_device *data = (void *) id->driver_data;
1007 card->helper = data->helper; 1010 card->helper = data->helper;
1008 card->firmware = data->firmware; 1011 card->firmware = data->firmware;
1012 card->cal_data = data->cal_data;
1009 card->reg = data->reg; 1013 card->reg = data->reg;
1010 card->sd_blksz_fw_dl = data->sd_blksz_fw_dl; 1014 card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
1011 } 1015 }
@@ -1034,6 +1038,8 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
1034 } 1038 }
1035 1039
1036 card->priv = priv; 1040 card->priv = priv;
1041 priv->btmrvl_dev.dev = &card->func->dev;
1042 priv->btmrvl_dev.cal_data = card->cal_data;
1037 1043
1038 /* Initialize the interface specific function pointers */ 1044 /* Initialize the interface specific function pointers */
1039 priv->hw_host_to_card = btmrvl_sdio_host_to_card; 1045 priv->hw_host_to_card = btmrvl_sdio_host_to_card;
@@ -1046,12 +1052,6 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
1046 goto disable_host_int; 1052 goto disable_host_int;
1047 } 1053 }
1048 1054
1049 priv->btmrvl_dev.psmode = 1;
1050 btmrvl_enable_ps(priv);
1051
1052 priv->btmrvl_dev.gpio_gap = 0xffff;
1053 btmrvl_send_hscfg_cmd(priv);
1054
1055 return 0; 1055 return 0;
1056 1056
1057disable_host_int: 1057disable_host_int:
@@ -1222,4 +1222,5 @@ MODULE_FIRMWARE("mrvl/sd8688_helper.bin");
1222MODULE_FIRMWARE("mrvl/sd8688.bin"); 1222MODULE_FIRMWARE("mrvl/sd8688.bin");
1223MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); 1223MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin");
1224MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin"); 1224MODULE_FIRMWARE("mrvl/sd8797_uapsta.bin");
1225MODULE_FIRMWARE("mrvl/sd8797_caldata.conf");
1225MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin"); 1226MODULE_FIRMWARE("mrvl/sd8897_uapsta.bin");
diff --git a/drivers/bluetooth/btmrvl_sdio.h b/drivers/bluetooth/btmrvl_sdio.h
index 43d35a609ca9..6872d9ecac07 100644
--- a/drivers/bluetooth/btmrvl_sdio.h
+++ b/drivers/bluetooth/btmrvl_sdio.h
@@ -85,6 +85,7 @@ struct btmrvl_sdio_card {
85 u32 ioport; 85 u32 ioport;
86 const char *helper; 86 const char *helper;
87 const char *firmware; 87 const char *firmware;
88 const char *cal_data;
88 const struct btmrvl_sdio_card_reg *reg; 89 const struct btmrvl_sdio_card_reg *reg;
89 u16 sd_blksz_fw_dl; 90 u16 sd_blksz_fw_dl;
90 u8 rx_unit; 91 u8 rx_unit;
@@ -94,6 +95,7 @@ struct btmrvl_sdio_card {
94struct btmrvl_sdio_device { 95struct btmrvl_sdio_device {
95 const char *helper; 96 const char *helper;
96 const char *firmware; 97 const char *firmware;
98 const char *cal_data;
97 const struct btmrvl_sdio_card_reg *reg; 99 const struct btmrvl_sdio_card_reg *reg;
98 u16 sd_blksz_fw_dl; 100 u16 sd_blksz_fw_dl;
99}; 101};
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index d8b7aed6e4a9..c04a3e6fb37c 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -24,6 +24,7 @@
24 */ 24 */
25 25
26#include <linux/module.h> 26#include <linux/module.h>
27#include <asm/unaligned.h>
27 28
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/init.h> 30#include <linux/init.h>
@@ -39,17 +40,17 @@
39#include <net/bluetooth/bluetooth.h> 40#include <net/bluetooth/bluetooth.h>
40#include <net/bluetooth/hci_core.h> 41#include <net/bluetooth/hci_core.h>
41 42
42#define VERSION "1.3" 43#define VERSION "1.4"
43 44
44static bool amp; 45static bool amp;
45 46
46struct vhci_data { 47struct vhci_data {
47 struct hci_dev *hdev; 48 struct hci_dev *hdev;
48 49
49 unsigned long flags;
50
51 wait_queue_head_t read_wait; 50 wait_queue_head_t read_wait;
52 struct sk_buff_head readq; 51 struct sk_buff_head readq;
52
53 struct delayed_work open_timeout;
53}; 54};
54 55
55static int vhci_open_dev(struct hci_dev *hdev) 56static int vhci_open_dev(struct hci_dev *hdev)
@@ -99,16 +100,62 @@ static int vhci_send_frame(struct sk_buff *skb)
99 skb_queue_tail(&data->readq, skb); 100 skb_queue_tail(&data->readq, skb);
100 101
101 wake_up_interruptible(&data->read_wait); 102 wake_up_interruptible(&data->read_wait);
103 return 0;
104}
105
106static int vhci_create_device(struct vhci_data *data, __u8 dev_type)
107{
108 struct hci_dev *hdev;
109 struct sk_buff *skb;
110
111 skb = bt_skb_alloc(4, GFP_KERNEL);
112 if (!skb)
113 return -ENOMEM;
114
115 hdev = hci_alloc_dev();
116 if (!hdev) {
117 kfree_skb(skb);
118 return -ENOMEM;
119 }
120
121 data->hdev = hdev;
122
123 hdev->bus = HCI_VIRTUAL;
124 hdev->dev_type = dev_type;
125 hci_set_drvdata(hdev, data);
126
127 hdev->open = vhci_open_dev;
128 hdev->close = vhci_close_dev;
129 hdev->flush = vhci_flush;
130 hdev->send = vhci_send_frame;
102 131
132 if (hci_register_dev(hdev) < 0) {
133 BT_ERR("Can't register HCI device");
134 hci_free_dev(hdev);
135 data->hdev = NULL;
136 kfree_skb(skb);
137 return -EBUSY;
138 }
139
140 bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
141
142 *skb_put(skb, 1) = 0xff;
143 *skb_put(skb, 1) = dev_type;
144 put_unaligned_le16(hdev->id, skb_put(skb, 2));
145 skb_queue_tail(&data->readq, skb);
146
147 wake_up_interruptible(&data->read_wait);
103 return 0; 148 return 0;
104} 149}
105 150
106static inline ssize_t vhci_get_user(struct vhci_data *data, 151static inline ssize_t vhci_get_user(struct vhci_data *data,
107 const char __user *buf, size_t count) 152 const char __user *buf, size_t count)
108{ 153{
109 struct sk_buff *skb; 154 struct sk_buff *skb;
155 __u8 pkt_type, dev_type;
156 int ret;
110 157
111 if (count > HCI_MAX_FRAME_SIZE) 158 if (count < 2 || count > HCI_MAX_FRAME_SIZE)
112 return -EINVAL; 159 return -EINVAL;
113 160
114 skb = bt_skb_alloc(count, GFP_KERNEL); 161 skb = bt_skb_alloc(count, GFP_KERNEL);
@@ -120,27 +167,70 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
120 return -EFAULT; 167 return -EFAULT;
121 } 168 }
122 169
123 skb->dev = (void *) data->hdev; 170 pkt_type = *((__u8 *) skb->data);
124 bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
125 skb_pull(skb, 1); 171 skb_pull(skb, 1);
126 172
127 hci_recv_frame(skb); 173 switch (pkt_type) {
174 case HCI_EVENT_PKT:
175 case HCI_ACLDATA_PKT:
176 case HCI_SCODATA_PKT:
177 if (!data->hdev) {
178 kfree_skb(skb);
179 return -ENODEV;
180 }
181
182 skb->dev = (void *) data->hdev;
183 bt_cb(skb)->pkt_type = pkt_type;
184
185 ret = hci_recv_frame(skb);
186 break;
187
188 case HCI_VENDOR_PKT:
189 if (data->hdev) {
190 kfree_skb(skb);
191 return -EBADFD;
192 }
128 193
129 return count; 194 cancel_delayed_work_sync(&data->open_timeout);
195
196 dev_type = *((__u8 *) skb->data);
197 skb_pull(skb, 1);
198
199 if (skb->len > 0) {
200 kfree_skb(skb);
201 return -EINVAL;
202 }
203
204 kfree_skb(skb);
205
206 if (dev_type != HCI_BREDR && dev_type != HCI_AMP)
207 return -EINVAL;
208
209 ret = vhci_create_device(data, dev_type);
210 break;
211
212 default:
213 kfree_skb(skb);
214 return -EINVAL;
215 }
216
217 return (ret < 0) ? ret : count;
130} 218}
131 219
132static inline ssize_t vhci_put_user(struct vhci_data *data, 220static inline ssize_t vhci_put_user(struct vhci_data *data,
133 struct sk_buff *skb, char __user *buf, int count) 221 struct sk_buff *skb,
222 char __user *buf, int count)
134{ 223{
135 char __user *ptr = buf; 224 char __user *ptr = buf;
136 int len, total = 0; 225 int len;
137 226
138 len = min_t(unsigned int, skb->len, count); 227 len = min_t(unsigned int, skb->len, count);
139 228
140 if (copy_to_user(ptr, skb->data, len)) 229 if (copy_to_user(ptr, skb->data, len))
141 return -EFAULT; 230 return -EFAULT;
142 231
143 total += len; 232 if (!data->hdev)
233 return len;
144 234
145 data->hdev->stat.byte_tx += len; 235 data->hdev->stat.byte_tx += len;
146 236
@@ -148,21 +238,19 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
148 case HCI_COMMAND_PKT: 238 case HCI_COMMAND_PKT:
149 data->hdev->stat.cmd_tx++; 239 data->hdev->stat.cmd_tx++;
150 break; 240 break;
151
152 case HCI_ACLDATA_PKT: 241 case HCI_ACLDATA_PKT:
153 data->hdev->stat.acl_tx++; 242 data->hdev->stat.acl_tx++;
154 break; 243 break;
155
156 case HCI_SCODATA_PKT: 244 case HCI_SCODATA_PKT:
157 data->hdev->stat.sco_tx++; 245 data->hdev->stat.sco_tx++;
158 break; 246 break;
159 } 247 }
160 248
161 return total; 249 return len;
162} 250}
163 251
164static ssize_t vhci_read(struct file *file, 252static ssize_t vhci_read(struct file *file,
165 char __user *buf, size_t count, loff_t *pos) 253 char __user *buf, size_t count, loff_t *pos)
166{ 254{
167 struct vhci_data *data = file->private_data; 255 struct vhci_data *data = file->private_data;
168 struct sk_buff *skb; 256 struct sk_buff *skb;
@@ -185,7 +273,7 @@ static ssize_t vhci_read(struct file *file,
185 } 273 }
186 274
187 ret = wait_event_interruptible(data->read_wait, 275 ret = wait_event_interruptible(data->read_wait,
188 !skb_queue_empty(&data->readq)); 276 !skb_queue_empty(&data->readq));
189 if (ret < 0) 277 if (ret < 0)
190 break; 278 break;
191 } 279 }
@@ -194,7 +282,7 @@ static ssize_t vhci_read(struct file *file,
194} 282}
195 283
196static ssize_t vhci_write(struct file *file, 284static ssize_t vhci_write(struct file *file,
197 const char __user *buf, size_t count, loff_t *pos) 285 const char __user *buf, size_t count, loff_t *pos)
198{ 286{
199 struct vhci_data *data = file->private_data; 287 struct vhci_data *data = file->private_data;
200 288
@@ -213,10 +301,17 @@ static unsigned int vhci_poll(struct file *file, poll_table *wait)
213 return POLLOUT | POLLWRNORM; 301 return POLLOUT | POLLWRNORM;
214} 302}
215 303
304static void vhci_open_timeout(struct work_struct *work)
305{
306 struct vhci_data *data = container_of(work, struct vhci_data,
307 open_timeout.work);
308
309 vhci_create_device(data, amp ? HCI_AMP : HCI_BREDR);
310}
311
216static int vhci_open(struct inode *inode, struct file *file) 312static int vhci_open(struct inode *inode, struct file *file)
217{ 313{
218 struct vhci_data *data; 314 struct vhci_data *data;
219 struct hci_dev *hdev;
220 315
221 data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL); 316 data = kzalloc(sizeof(struct vhci_data), GFP_KERNEL);
222 if (!data) 317 if (!data)
@@ -225,35 +320,13 @@ static int vhci_open(struct inode *inode, struct file *file)
225 skb_queue_head_init(&data->readq); 320 skb_queue_head_init(&data->readq);
226 init_waitqueue_head(&data->read_wait); 321 init_waitqueue_head(&data->read_wait);
227 322
228 hdev = hci_alloc_dev(); 323 INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
229 if (!hdev) {
230 kfree(data);
231 return -ENOMEM;
232 }
233
234 data->hdev = hdev;
235
236 hdev->bus = HCI_VIRTUAL;
237 hci_set_drvdata(hdev, data);
238
239 if (amp)
240 hdev->dev_type = HCI_AMP;
241
242 hdev->open = vhci_open_dev;
243 hdev->close = vhci_close_dev;
244 hdev->flush = vhci_flush;
245 hdev->send = vhci_send_frame;
246
247 if (hci_register_dev(hdev) < 0) {
248 BT_ERR("Can't register HCI device");
249 kfree(data);
250 hci_free_dev(hdev);
251 return -EBUSY;
252 }
253 324
254 file->private_data = data; 325 file->private_data = data;
255 nonseekable_open(inode, file); 326 nonseekable_open(inode, file);
256 327
328 schedule_delayed_work(&data->open_timeout, msecs_to_jiffies(1000));
329
257 return 0; 330 return 0;
258} 331}
259 332
@@ -262,8 +335,12 @@ static int vhci_release(struct inode *inode, struct file *file)
262 struct vhci_data *data = file->private_data; 335 struct vhci_data *data = file->private_data;
263 struct hci_dev *hdev = data->hdev; 336 struct hci_dev *hdev = data->hdev;
264 337
265 hci_unregister_dev(hdev); 338 cancel_delayed_work_sync(&data->open_timeout);
266 hci_free_dev(hdev); 339
340 if (hdev) {
341 hci_unregister_dev(hdev);
342 hci_free_dev(hdev);
343 }
267 344
268 file->private_data = NULL; 345 file->private_data = NULL;
269 kfree(data); 346 kfree(data);
@@ -309,3 +386,4 @@ MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
309MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION); 386MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
310MODULE_VERSION(VERSION); 387MODULE_VERSION(VERSION);
311MODULE_LICENSE("GPL"); 388MODULE_LICENSE("GPL");
389MODULE_ALIAS("devname:vhci");