btrtl.c (91de76e661a266731fc2889a398ad1694df9d523) btrtl.c (2064ee332e4c1b7495cf68b84355c213d8fe71fd)
1/*
2 * Bluetooth support for Realtek devices
3 *
4 * Copyright (C) 2015 Endless Mobile, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 41 unchanged lines hidden (view full) ---

50
51 if (skb->len != sizeof(*rom_version)) {
52 BT_ERR("%s: RTL version event length mismatch", hdev->name);
53 kfree_skb(skb);
54 return -EIO;
55 }
56
57 rom_version = (struct rtl_rom_version_evt *)skb->data;
1/*
2 * Bluetooth support for Realtek devices
3 *
4 * Copyright (C) 2015 Endless Mobile, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or

--- 41 unchanged lines hidden (view full) ---

50
51 if (skb->len != sizeof(*rom_version)) {
52 BT_ERR("%s: RTL version event length mismatch", hdev->name);
53 kfree_skb(skb);
54 return -EIO;
55 }
56
57 rom_version = (struct rtl_rom_version_evt *)skb->data;
58 BT_INFO("%s: rom_version status=%x version=%x",
59 hdev->name, rom_version->status, rom_version->version);
58 bt_dev_info(hdev, "rom_version status=%x version=%x",
59 rom_version->status, rom_version->version);
60
61 *version = rom_version->version;
62
63 kfree_skb(skb);
64 return 0;
65}
66
67static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,

--- 200 unchanged lines hidden (view full) ---

268 return ret;
269}
270
271static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
272{
273 const struct firmware *fw;
274 int ret;
275
60
61 *version = rom_version->version;
62
63 kfree_skb(skb);
64 return 0;
65}
66
67static int rtl8723b_parse_firmware(struct hci_dev *hdev, u16 lmp_subver,

--- 200 unchanged lines hidden (view full) ---

268 return ret;
269}
270
271static int rtl_load_config(struct hci_dev *hdev, const char *name, u8 **buff)
272{
273 const struct firmware *fw;
274 int ret;
275
276 BT_INFO("%s: rtl: loading %s", hdev->name, name);
276 bt_dev_info(hdev, "rtl: loading %s", name);
277 ret = request_firmware(&fw, name, &hdev->dev);
278 if (ret < 0)
279 return ret;
280 ret = fw->size;
281 *buff = kmemdup(fw->data, ret, GFP_KERNEL);
282 if (!*buff)
283 ret = -ENOMEM;
284
285 release_firmware(fw);
286
287 return ret;
288}
289
290static int btrtl_setup_rtl8723a(struct hci_dev *hdev)
291{
292 const struct firmware *fw;
293 int ret;
294
277 ret = request_firmware(&fw, name, &hdev->dev);
278 if (ret < 0)
279 return ret;
280 ret = fw->size;
281 *buff = kmemdup(fw->data, ret, GFP_KERNEL);
282 if (!*buff)
283 ret = -ENOMEM;
284
285 release_firmware(fw);
286
287 return ret;
288}
289
290static int btrtl_setup_rtl8723a(struct hci_dev *hdev)
291{
292 const struct firmware *fw;
293 int ret;
294
295 BT_INFO("%s: rtl: loading rtl_bt/rtl8723a_fw.bin", hdev->name);
295 bt_dev_info(hdev, "rtl: loading rtl_bt/rtl8723a_fw.bin");
296 ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev);
297 if (ret < 0) {
298 BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
299 return ret;
300 }
301
302 if (fw->size < 8) {
303 ret = -EINVAL;

--- 54 unchanged lines hidden (view full) ---

358 cfg_sz = 0;
359 if (config_needed)
360 BT_ERR("Necessary config file %s not found\n",
361 cfg_name);
362 }
363 } else
364 cfg_sz = 0;
365
296 ret = request_firmware(&fw, "rtl_bt/rtl8723a_fw.bin", &hdev->dev);
297 if (ret < 0) {
298 BT_ERR("%s: Failed to load rtl_bt/rtl8723a_fw.bin", hdev->name);
299 return ret;
300 }
301
302 if (fw->size < 8) {
303 ret = -EINVAL;

--- 54 unchanged lines hidden (view full) ---

358 cfg_sz = 0;
359 if (config_needed)
360 BT_ERR("Necessary config file %s not found\n",
361 cfg_name);
362 }
363 } else
364 cfg_sz = 0;
365
366 BT_INFO("%s: rtl: loading %s", hdev->name, fw_name);
366 bt_dev_info(hdev, "rtl: loading %s", fw_name);
367 ret = request_firmware(&fw, fw_name, &hdev->dev);
368 if (ret < 0) {
369 BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
370 goto err_req_fw;
371 }
372
373 ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data);
374 if (ret < 0)

--- 10 unchanged lines hidden (view full) ---

385 kfree(fw_data);
386
387 memcpy(tbuff + ret, cfg_buff, cfg_sz);
388 ret += cfg_sz;
389
390 fw_data = tbuff;
391 }
392
367 ret = request_firmware(&fw, fw_name, &hdev->dev);
368 if (ret < 0) {
369 BT_ERR("%s: Failed to load %s", hdev->name, fw_name);
370 goto err_req_fw;
371 }
372
373 ret = rtl8723b_parse_firmware(hdev, lmp_subver, fw, &fw_data);
374 if (ret < 0)

--- 10 unchanged lines hidden (view full) ---

385 kfree(fw_data);
386
387 memcpy(tbuff + ret, cfg_buff, cfg_sz);
388 ret += cfg_sz;
389
390 fw_data = tbuff;
391 }
392
393 BT_INFO("cfg_sz %d, total size %d", cfg_sz, ret);
393 bt_dev_info(hdev, "cfg_sz %d, total size %d", cfg_sz, ret);
394
395 ret = rtl_download_firmware(hdev, fw_data, ret);
396
397out:
398 release_firmware(fw);
399 kfree(fw_data);
400err_req_fw:
401 if (cfg_sz)

--- 29 unchanged lines hidden (view full) ---

431 struct hci_rp_read_local_version *resp;
432 u16 lmp_subver;
433
434 skb = btrtl_read_local_version(hdev);
435 if (IS_ERR(skb))
436 return -PTR_ERR(skb);
437
438 resp = (struct hci_rp_read_local_version *)skb->data;
394
395 ret = rtl_download_firmware(hdev, fw_data, ret);
396
397out:
398 release_firmware(fw);
399 kfree(fw_data);
400err_req_fw:
401 if (cfg_sz)

--- 29 unchanged lines hidden (view full) ---

431 struct hci_rp_read_local_version *resp;
432 u16 lmp_subver;
433
434 skb = btrtl_read_local_version(hdev);
435 if (IS_ERR(skb))
436 return -PTR_ERR(skb);
437
438 resp = (struct hci_rp_read_local_version *)skb->data;
439 BT_INFO("%s: rtl: examining hci_ver=%02x hci_rev=%04x lmp_ver=%02x "
440 "lmp_subver=%04x", hdev->name, resp->hci_ver, resp->hci_rev,
441 resp->lmp_ver, resp->lmp_subver);
439 bt_dev_info(hdev, "rtl: examining hci_ver=%02x hci_rev=%04x "
440 "lmp_ver=%02x lmp_subver=%04x",
441 resp->hci_ver, resp->hci_rev,
442 resp->lmp_ver, resp->lmp_subver);
442
443 lmp_subver = le16_to_cpu(resp->lmp_subver);
444 kfree_skb(skb);
445
446 /* Match a set of subver values that correspond to stock firmware,
447 * which is not compatible with standard btusb.
448 * If matched, upload an alternative firmware that does conform to
449 * standard btusb. Once that firmware is uploaded, the subver changes

--- 11 unchanged lines hidden (view full) ---

461 "rtl_bt/rtl8821a_fw.bin");
462 case RTL_ROM_LMP_8761A:
463 return btrtl_setup_rtl8723b(hdev, lmp_subver,
464 "rtl_bt/rtl8761a_fw.bin");
465 case RTL_ROM_LMP_8822B:
466 return btrtl_setup_rtl8723b(hdev, lmp_subver,
467 "rtl_bt/rtl8822b_fw.bin");
468 default:
443
444 lmp_subver = le16_to_cpu(resp->lmp_subver);
445 kfree_skb(skb);
446
447 /* Match a set of subver values that correspond to stock firmware,
448 * which is not compatible with standard btusb.
449 * If matched, upload an alternative firmware that does conform to
450 * standard btusb. Once that firmware is uploaded, the subver changes

--- 11 unchanged lines hidden (view full) ---

462 "rtl_bt/rtl8821a_fw.bin");
463 case RTL_ROM_LMP_8761A:
464 return btrtl_setup_rtl8723b(hdev, lmp_subver,
465 "rtl_bt/rtl8761a_fw.bin");
466 case RTL_ROM_LMP_8822B:
467 return btrtl_setup_rtl8723b(hdev, lmp_subver,
468 "rtl_bt/rtl8822b_fw.bin");
469 default:
469 BT_INFO("rtl: assuming no firmware upload needed.");
470 bt_dev_info(hdev, "rtl: assuming no firmware upload needed");
470 return 0;
471 }
472}
473EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
474
475MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
476MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
477MODULE_VERSION(VERSION);
478MODULE_LICENSE("GPL");
471 return 0;
472 }
473}
474EXPORT_SYMBOL_GPL(btrtl_setup_realtek);
475
476MODULE_AUTHOR("Daniel Drake <drake@endlessm.com>");
477MODULE_DESCRIPTION("Bluetooth support for Realtek devices ver " VERSION);
478MODULE_VERSION(VERSION);
479MODULE_LICENSE("GPL");