aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bluetooth/btmrvl_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bluetooth/btmrvl_main.c')
-rw-r--r--drivers/bluetooth/btmrvl_main.c269
1 files changed, 176 insertions, 93 deletions
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