diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/bluetooth/btbcm.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/bluetooth/btbcm.c')
| -rw-r--r-- | drivers/bluetooth/btbcm.c | 49 | 
1 files changed, 45 insertions, 4 deletions
diff --git a/drivers/bluetooth/btbcm.c b/drivers/bluetooth/btbcm.c index 3006e2a0f37e..de2ea589aa49 100644 --- a/drivers/bluetooth/btbcm.c +++ b/drivers/bluetooth/btbcm.c @@ -6,6 +6,7 @@   *  Copyright (C) 2015  Intel Corporation   */ +#include <linux/efi.h>  #include <linux/module.h>  #include <linux/firmware.h>  #include <linux/dmi.h> @@ -34,6 +35,43 @@  /* For kmalloc-ing the fw-name array instead of putting it on the stack */  typedef char bcm_fw_name[BCM_FW_NAME_LEN]; +#ifdef CONFIG_EFI +static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev) +{ +	efi_guid_t guid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61, 0xb5, 0x1f, +				   0x43, 0x26, 0x81, 0x23, 0xd1, 0x13); +	bdaddr_t efi_bdaddr, bdaddr; +	efi_status_t status; +	unsigned long len; +	int ret; + +	if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE)) +		return -EOPNOTSUPP; + +	len = sizeof(efi_bdaddr); +	status = efi.get_variable(L"BDADDR", &guid, NULL, &len, &efi_bdaddr); +	if (status != EFI_SUCCESS) +		return -ENXIO; + +	if (len != sizeof(efi_bdaddr)) +		return -EIO; + +	baswap(&bdaddr, &efi_bdaddr); + +	ret = btbcm_set_bdaddr(hdev, &bdaddr); +	if (ret) +		return ret; + +	bt_dev_info(hdev, "BCM: Using EFI device address (%pMR)", &bdaddr); +	return 0; +} +#else +static int btbcm_set_bdaddr_from_efi(struct hci_dev *hdev) +{ +	return -EOPNOTSUPP; +} +#endif +  int btbcm_check_bdaddr(struct hci_dev *hdev)  {  	struct hci_rp_read_bd_addr *bda; @@ -87,9 +125,12 @@ int btbcm_check_bdaddr(struct hci_dev *hdev)  	    !bacmp(&bda->bdaddr, BDADDR_BCM4345C5) ||  	    !bacmp(&bda->bdaddr, BDADDR_BCM43430A0) ||  	    !bacmp(&bda->bdaddr, BDADDR_BCM43341B)) { -		bt_dev_info(hdev, "BCM: Using default device address (%pMR)", -			    &bda->bdaddr); -		set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); +		/* Try falling back to BDADDR EFI variable */ +		if (btbcm_set_bdaddr_from_efi(hdev) != 0) { +			bt_dev_info(hdev, "BCM: Using default device address (%pMR)", +				    &bda->bdaddr); +			set_bit(HCI_QUIRK_INVALID_BDADDR, &hdev->quirks); +		}  	}  	kfree_skb(skb); @@ -511,7 +552,7 @@ static const char *btbcm_get_board_name(struct device *dev)  	len = strlen(tmp) + 1;  	board_type = devm_kzalloc(dev, len, GFP_KERNEL);  	strscpy(board_type, tmp, len); -	for (i = 0; i < board_type[i]; i++) { +	for (i = 0; i < len; i++) {  		if (board_type[i] == '/')  			board_type[i] = '-';  	}  |