diff options
Diffstat (limited to 'drivers/bluetooth/btintel.c')
| -rw-r--r-- | drivers/bluetooth/btintel.c | 88 | 
1 files changed, 71 insertions, 17 deletions
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c index 6ba7f5d1b837..0c855c3ee1c1 100644 --- a/drivers/bluetooth/btintel.c +++ b/drivers/bluetooth/btintel.c @@ -245,7 +245,7 @@ static int btintel_set_diag_combined(struct hci_dev *hdev, bool enable)  	return ret;  } -static void btintel_hw_error(struct hci_dev *hdev, u8 code) +void btintel_hw_error(struct hci_dev *hdev, u8 code)  {  	struct sk_buff *skb;  	u8 type = 0x00; @@ -277,6 +277,7 @@ static void btintel_hw_error(struct hci_dev *hdev, u8 code)  	kfree_skb(skb);  } +EXPORT_SYMBOL_GPL(btintel_hw_error);  int btintel_version_info(struct hci_dev *hdev, struct intel_version *ver)  { @@ -455,8 +456,8 @@ int btintel_read_version(struct hci_dev *hdev, struct intel_version *ver)  }  EXPORT_SYMBOL_GPL(btintel_read_version); -static int btintel_version_info_tlv(struct hci_dev *hdev, -				    struct intel_version_tlv *version) +int btintel_version_info_tlv(struct hci_dev *hdev, +			     struct intel_version_tlv *version)  {  	const char *variant; @@ -481,6 +482,7 @@ static int btintel_version_info_tlv(struct hci_dev *hdev,  	case 0x19:	/* Slr-F */  	case 0x1b:      /* Mgr */  	case 0x1c:	/* Gale Peak (GaP) */ +	case 0x1e:	/* BlazarI (Bzr) */  		break;  	default:  		bt_dev_err(hdev, "Unsupported Intel hardware variant (0x%x)", @@ -489,7 +491,7 @@ static int btintel_version_info_tlv(struct hci_dev *hdev,  	}  	switch (version->img_type) { -	case 0x01: +	case BTINTEL_IMG_BOOTLOADER:  		variant = "Bootloader";  		/* It is required that every single firmware fragment is acknowledged  		 * with a command complete event. If the boot parameters indicate @@ -521,7 +523,10 @@ static int btintel_version_info_tlv(struct hci_dev *hdev,  			    version->min_fw_build_nn, version->min_fw_build_cw,  			    2000 + version->min_fw_build_yy);  		break; -	case 0x03: +	case BTINTEL_IMG_IML: +		variant = "Intermediate loader"; +		break; +	case BTINTEL_IMG_OP:  		variant = "Firmware";  		break;  	default: @@ -535,15 +540,16 @@ static int btintel_version_info_tlv(struct hci_dev *hdev,  	bt_dev_info(hdev, "%s timestamp %u.%u buildtype %u build %u", variant,  		    2000 + (version->timestamp >> 8), version->timestamp & 0xff,  		    version->build_type, version->build_num); -	if (version->img_type == 0x03) +	if (version->img_type == BTINTEL_IMG_OP)  		bt_dev_info(hdev, "Firmware SHA1: 0x%8.8x", version->git_sha1);  	return 0;  } +EXPORT_SYMBOL_GPL(btintel_version_info_tlv); -static int btintel_parse_version_tlv(struct hci_dev *hdev, -				     struct intel_version_tlv *version, -				     struct sk_buff *skb) +int btintel_parse_version_tlv(struct hci_dev *hdev, +			      struct intel_version_tlv *version, +			      struct sk_buff *skb)  {  	/* Consume Command Complete Status field */  	skb_pull(skb, 1); @@ -645,6 +651,7 @@ static int btintel_parse_version_tlv(struct hci_dev *hdev,  	return 0;  } +EXPORT_SYMBOL_GPL(btintel_parse_version_tlv);  static int btintel_read_version_tlv(struct hci_dev *hdev,  				    struct intel_version_tlv *version) @@ -1172,7 +1179,7 @@ static int btintel_download_fw_tlv(struct hci_dev *hdev,  	 * If the firmware version has changed that means it needs to be reset  	 * to bootloader when operational so the new firmware can be loaded.  	 */ -	if (ver->img_type == 0x03) +	if (ver->img_type == BTINTEL_IMG_OP)  		return -EINVAL;  	/* iBT hardware variants 0x0b, 0x0c, 0x11, 0x12, 0x13, 0x14 support @@ -2194,10 +2201,26 @@ static void btintel_get_fw_name_tlv(const struct intel_version_tlv *ver,  				    char *fw_name, size_t len,  				    const char *suffix)  { +	const char *format;  	/* The firmware file name for new generation controllers will be  	 * ibt-<cnvi_top type+cnvi_top step>-<cnvr_top type+cnvr_top step>  	 */ -	snprintf(fw_name, len, "intel/ibt-%04x-%04x.%s", +	switch (ver->cnvi_top & 0xfff) { +	/* Only Blazar  product supports downloading of intermediate loader +	 * image +	 */ +	case BTINTEL_CNVI_BLAZARI: +		if (ver->img_type == BTINTEL_IMG_BOOTLOADER) +			format = "intel/ibt-%04x-%04x-iml.%s"; +		else +			format = "intel/ibt-%04x-%04x.%s"; +		break; +	default: +			format = "intel/ibt-%04x-%04x.%s"; +		break; +	} + +	snprintf(fw_name, len, format,  		 INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvi_top),  					  INTEL_CNVX_TOP_STEP(ver->cnvi_top)),  		 INTEL_CNVX_TOP_PACK_SWAB(INTEL_CNVX_TOP_TYPE(ver->cnvr_top), @@ -2230,7 +2253,7 @@ static int btintel_prepare_fw_download_tlv(struct hci_dev *hdev,  	 * It is not possible to use the Secure Boot Parameters in this  	 * case since that command is only available in bootloader mode.  	 */ -	if (ver->img_type == 0x03) { +	if (ver->img_type == BTINTEL_IMG_OP) {  		btintel_clear_flag(hdev, INTEL_BOOTLOADER);  		btintel_check_bdaddr(hdev);  	} else { @@ -2577,8 +2600,8 @@ static void btintel_set_dsm_reset_method(struct hci_dev *hdev,  	data->acpi_reset_method = btintel_acpi_reset_method;  } -static int btintel_bootloader_setup_tlv(struct hci_dev *hdev, -					struct intel_version_tlv *ver) +int btintel_bootloader_setup_tlv(struct hci_dev *hdev, +				 struct intel_version_tlv *ver)  {  	u32 boot_param;  	char ddcname[64]; @@ -2600,13 +2623,30 @@ static int btintel_bootloader_setup_tlv(struct hci_dev *hdev,  		return err;  	/* check if controller is already having an operational firmware */ -	if (ver->img_type == 0x03) +	if (ver->img_type == BTINTEL_IMG_OP)  		goto finish;  	err = btintel_boot(hdev, boot_param);  	if (err)  		return err; +	err = btintel_read_version_tlv(hdev, ver); +	if (err) +		return err; + +	/* If image type returned is BTINTEL_IMG_IML, then controller supports +	 * intermediae loader image +	 */ +	if (ver->img_type == BTINTEL_IMG_IML) { +		err = btintel_prepare_fw_download_tlv(hdev, ver, &boot_param); +		if (err) +			return err; + +		err = btintel_boot(hdev, boot_param); +		if (err) +			return err; +	} +  	btintel_clear_flag(hdev, INTEL_BOOTLOADER);  	btintel_get_fw_name_tlv(ver, ddcname, sizeof(ddcname), "ddc"); @@ -2645,8 +2685,9 @@ finish:  	return 0;  } +EXPORT_SYMBOL_GPL(btintel_bootloader_setup_tlv); -static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant) +void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)  {  	switch (hw_variant) {  	/* Legacy bootloader devices that supports MSFT Extension */ @@ -2662,6 +2703,7 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)  	case 0x19:  	case 0x1b:  	case 0x1c: +	case 0x1e:  		hci_set_msft_opcode(hdev, 0xFC1E);  		break;  	default: @@ -2669,6 +2711,7 @@ static void btintel_set_msft_opcode(struct hci_dev *hdev, u8 hw_variant)  		break;  	}  } +EXPORT_SYMBOL_GPL(btintel_set_msft_opcode);  static void btintel_print_fseq_info(struct hci_dev *hdev)  { @@ -2920,6 +2963,11 @@ static int btintel_setup_combined(struct hci_dev *hdev)  			err = -EINVAL;  		} +		hci_set_hw_info(hdev, +				"INTEL platform=%u variant=%u revision=%u", +				ver.hw_platform, ver.hw_variant, +				ver.hw_revision); +  		goto exit_error;  	} @@ -2996,6 +3044,7 @@ static int btintel_setup_combined(struct hci_dev *hdev)  	case 0x19:  	case 0x1b:  	case 0x1c: +	case 0x1e:  		/* Display version information of TLV type */  		btintel_version_info_tlv(hdev, &ver_tlv); @@ -3024,13 +3073,17 @@ static int btintel_setup_combined(struct hci_dev *hdev)  		break;  	} +	hci_set_hw_info(hdev, "INTEL platform=%u variant=%u", +			INTEL_HW_PLATFORM(ver_tlv.cnvi_bt), +			INTEL_HW_VARIANT(ver_tlv.cnvi_bt)); +  exit_error:  	kfree_skb(skb);  	return err;  } -static int btintel_shutdown_combined(struct hci_dev *hdev) +int btintel_shutdown_combined(struct hci_dev *hdev)  {  	struct sk_buff *skb;  	int ret; @@ -3064,6 +3117,7 @@ static int btintel_shutdown_combined(struct hci_dev *hdev)  	return 0;  } +EXPORT_SYMBOL_GPL(btintel_shutdown_combined);  int btintel_configure_setup(struct hci_dev *hdev, const char *driver_name)  {  |