162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *  Bluetooth support for Intel devices
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci *  Copyright (C) 2015  Intel Corporation
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/* List of tlv type */
1062306a36Sopenharmony_cienum {
1162306a36Sopenharmony_ci	INTEL_TLV_CNVI_TOP = 0x10,
1262306a36Sopenharmony_ci	INTEL_TLV_CNVR_TOP,
1362306a36Sopenharmony_ci	INTEL_TLV_CNVI_BT,
1462306a36Sopenharmony_ci	INTEL_TLV_CNVR_BT,
1562306a36Sopenharmony_ci	INTEL_TLV_CNVI_OTP,
1662306a36Sopenharmony_ci	INTEL_TLV_CNVR_OTP,
1762306a36Sopenharmony_ci	INTEL_TLV_DEV_REV_ID,
1862306a36Sopenharmony_ci	INTEL_TLV_USB_VENDOR_ID,
1962306a36Sopenharmony_ci	INTEL_TLV_USB_PRODUCT_ID,
2062306a36Sopenharmony_ci	INTEL_TLV_PCIE_VENDOR_ID,
2162306a36Sopenharmony_ci	INTEL_TLV_PCIE_DEVICE_ID,
2262306a36Sopenharmony_ci	INTEL_TLV_PCIE_SUBSYSTEM_ID,
2362306a36Sopenharmony_ci	INTEL_TLV_IMAGE_TYPE,
2462306a36Sopenharmony_ci	INTEL_TLV_TIME_STAMP,
2562306a36Sopenharmony_ci	INTEL_TLV_BUILD_TYPE,
2662306a36Sopenharmony_ci	INTEL_TLV_BUILD_NUM,
2762306a36Sopenharmony_ci	INTEL_TLV_FW_BUILD_PRODUCT,
2862306a36Sopenharmony_ci	INTEL_TLV_FW_BUILD_HW,
2962306a36Sopenharmony_ci	INTEL_TLV_FW_STEP,
3062306a36Sopenharmony_ci	INTEL_TLV_BT_SPEC,
3162306a36Sopenharmony_ci	INTEL_TLV_MFG_NAME,
3262306a36Sopenharmony_ci	INTEL_TLV_HCI_REV,
3362306a36Sopenharmony_ci	INTEL_TLV_LMP_SUBVER,
3462306a36Sopenharmony_ci	INTEL_TLV_OTP_PATCH_VER,
3562306a36Sopenharmony_ci	INTEL_TLV_SECURE_BOOT,
3662306a36Sopenharmony_ci	INTEL_TLV_KEY_FROM_HDR,
3762306a36Sopenharmony_ci	INTEL_TLV_OTP_LOCK,
3862306a36Sopenharmony_ci	INTEL_TLV_API_LOCK,
3962306a36Sopenharmony_ci	INTEL_TLV_DEBUG_LOCK,
4062306a36Sopenharmony_ci	INTEL_TLV_MIN_FW,
4162306a36Sopenharmony_ci	INTEL_TLV_LIMITED_CCE,
4262306a36Sopenharmony_ci	INTEL_TLV_SBE_TYPE,
4362306a36Sopenharmony_ci	INTEL_TLV_OTP_BDADDR,
4462306a36Sopenharmony_ci	INTEL_TLV_UNLOCKED_STATE
4562306a36Sopenharmony_ci};
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistruct intel_tlv {
4862306a36Sopenharmony_ci	u8 type;
4962306a36Sopenharmony_ci	u8 len;
5062306a36Sopenharmony_ci	u8 val[];
5162306a36Sopenharmony_ci} __packed;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistruct intel_version_tlv {
5462306a36Sopenharmony_ci	u32	cnvi_top;
5562306a36Sopenharmony_ci	u32	cnvr_top;
5662306a36Sopenharmony_ci	u32	cnvi_bt;
5762306a36Sopenharmony_ci	u32	cnvr_bt;
5862306a36Sopenharmony_ci	u16	dev_rev_id;
5962306a36Sopenharmony_ci	u8	img_type;
6062306a36Sopenharmony_ci	u16	timestamp;
6162306a36Sopenharmony_ci	u8	build_type;
6262306a36Sopenharmony_ci	u32	build_num;
6362306a36Sopenharmony_ci	u8	secure_boot;
6462306a36Sopenharmony_ci	u8	otp_lock;
6562306a36Sopenharmony_ci	u8	api_lock;
6662306a36Sopenharmony_ci	u8	debug_lock;
6762306a36Sopenharmony_ci	u8	min_fw_build_nn;
6862306a36Sopenharmony_ci	u8	min_fw_build_cw;
6962306a36Sopenharmony_ci	u8	min_fw_build_yy;
7062306a36Sopenharmony_ci	u8	limited_cce;
7162306a36Sopenharmony_ci	u8	sbe_type;
7262306a36Sopenharmony_ci	bdaddr_t otp_bd_addr;
7362306a36Sopenharmony_ci};
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistruct intel_version {
7662306a36Sopenharmony_ci	u8 status;
7762306a36Sopenharmony_ci	u8 hw_platform;
7862306a36Sopenharmony_ci	u8 hw_variant;
7962306a36Sopenharmony_ci	u8 hw_revision;
8062306a36Sopenharmony_ci	u8 fw_variant;
8162306a36Sopenharmony_ci	u8 fw_revision;
8262306a36Sopenharmony_ci	u8 fw_build_num;
8362306a36Sopenharmony_ci	u8 fw_build_ww;
8462306a36Sopenharmony_ci	u8 fw_build_yy;
8562306a36Sopenharmony_ci	u8 fw_patch_num;
8662306a36Sopenharmony_ci} __packed;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistruct intel_boot_params {
8962306a36Sopenharmony_ci	__u8     status;
9062306a36Sopenharmony_ci	__u8     otp_format;
9162306a36Sopenharmony_ci	__u8     otp_content;
9262306a36Sopenharmony_ci	__u8     otp_patch;
9362306a36Sopenharmony_ci	__le16   dev_revid;
9462306a36Sopenharmony_ci	__u8     secure_boot;
9562306a36Sopenharmony_ci	__u8     key_from_hdr;
9662306a36Sopenharmony_ci	__u8     key_type;
9762306a36Sopenharmony_ci	__u8     otp_lock;
9862306a36Sopenharmony_ci	__u8     api_lock;
9962306a36Sopenharmony_ci	__u8     debug_lock;
10062306a36Sopenharmony_ci	bdaddr_t otp_bdaddr;
10162306a36Sopenharmony_ci	__u8     min_fw_build_nn;
10262306a36Sopenharmony_ci	__u8     min_fw_build_cw;
10362306a36Sopenharmony_ci	__u8     min_fw_build_yy;
10462306a36Sopenharmony_ci	__u8     limited_cce;
10562306a36Sopenharmony_ci	__u8     unlocked_state;
10662306a36Sopenharmony_ci} __packed;
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistruct intel_bootup {
10962306a36Sopenharmony_ci	__u8     zero;
11062306a36Sopenharmony_ci	__u8     num_cmds;
11162306a36Sopenharmony_ci	__u8     source;
11262306a36Sopenharmony_ci	__u8     reset_type;
11362306a36Sopenharmony_ci	__u8     reset_reason;
11462306a36Sopenharmony_ci	__u8     ddc_status;
11562306a36Sopenharmony_ci} __packed;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistruct intel_secure_send_result {
11862306a36Sopenharmony_ci	__u8     result;
11962306a36Sopenharmony_ci	__le16   opcode;
12062306a36Sopenharmony_ci	__u8     status;
12162306a36Sopenharmony_ci} __packed;
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistruct intel_reset {
12462306a36Sopenharmony_ci	__u8     reset_type;
12562306a36Sopenharmony_ci	__u8     patch_enable;
12662306a36Sopenharmony_ci	__u8     ddc_reload;
12762306a36Sopenharmony_ci	__u8     boot_option;
12862306a36Sopenharmony_ci	__le32   boot_param;
12962306a36Sopenharmony_ci} __packed;
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistruct intel_debug_features {
13262306a36Sopenharmony_ci	__u8    page1[16];
13362306a36Sopenharmony_ci} __packed;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistruct intel_offload_use_cases {
13662306a36Sopenharmony_ci	__u8	status;
13762306a36Sopenharmony_ci	__u8	preset[8];
13862306a36Sopenharmony_ci} __packed;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#define INTEL_OP_PPAG_CMD		0xFE0B
14162306a36Sopenharmony_cistruct hci_ppag_enable_cmd {
14262306a36Sopenharmony_ci	__le32	ppag_enable_flags;
14362306a36Sopenharmony_ci} __packed;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci#define INTEL_TLV_TYPE_ID		0x01
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci#define INTEL_TLV_SYSTEM_EXCEPTION	0x00
14862306a36Sopenharmony_ci#define INTEL_TLV_FATAL_EXCEPTION	0x01
14962306a36Sopenharmony_ci#define INTEL_TLV_DEBUG_EXCEPTION	0x02
15062306a36Sopenharmony_ci#define INTEL_TLV_TEST_EXCEPTION	0xDE
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci#define INTEL_HW_PLATFORM(cnvx_bt)	((u8)(((cnvx_bt) & 0x0000ff00) >> 8))
15362306a36Sopenharmony_ci#define INTEL_HW_VARIANT(cnvx_bt)	((u8)(((cnvx_bt) & 0x003f0000) >> 16))
15462306a36Sopenharmony_ci#define INTEL_CNVX_TOP_TYPE(cnvx_top)	((cnvx_top) & 0x00000fff)
15562306a36Sopenharmony_ci#define INTEL_CNVX_TOP_STEP(cnvx_top)	(((cnvx_top) & 0x0f000000) >> 24)
15662306a36Sopenharmony_ci#define INTEL_CNVX_TOP_PACK_SWAB(t, s)	__swab16(((__u16)(((t) << 4) | (s))))
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cienum {
15962306a36Sopenharmony_ci	INTEL_BOOTLOADER,
16062306a36Sopenharmony_ci	INTEL_DOWNLOADING,
16162306a36Sopenharmony_ci	INTEL_FIRMWARE_LOADED,
16262306a36Sopenharmony_ci	INTEL_FIRMWARE_FAILED,
16362306a36Sopenharmony_ci	INTEL_BOOTING,
16462306a36Sopenharmony_ci	INTEL_BROKEN_INITIAL_NCMD,
16562306a36Sopenharmony_ci	INTEL_BROKEN_SHUTDOWN_LED,
16662306a36Sopenharmony_ci	INTEL_ROM_LEGACY,
16762306a36Sopenharmony_ci	INTEL_ROM_LEGACY_NO_WBS_SUPPORT,
16862306a36Sopenharmony_ci	INTEL_ACPI_RESET_ACTIVE,
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	__INTEL_NUM_FLAGS,
17162306a36Sopenharmony_ci};
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistruct btintel_data {
17462306a36Sopenharmony_ci	DECLARE_BITMAP(flags, __INTEL_NUM_FLAGS);
17562306a36Sopenharmony_ci	int (*acpi_reset_method)(struct hci_dev *hdev);
17662306a36Sopenharmony_ci};
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci#define btintel_set_flag(hdev, nr)					\
17962306a36Sopenharmony_ci	do {								\
18062306a36Sopenharmony_ci		struct btintel_data *intel = hci_get_priv((hdev));	\
18162306a36Sopenharmony_ci		set_bit((nr), intel->flags);				\
18262306a36Sopenharmony_ci	} while (0)
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#define btintel_clear_flag(hdev, nr)					\
18562306a36Sopenharmony_ci	do {								\
18662306a36Sopenharmony_ci		struct btintel_data *intel = hci_get_priv((hdev));	\
18762306a36Sopenharmony_ci		clear_bit((nr), intel->flags);				\
18862306a36Sopenharmony_ci	} while (0)
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#define btintel_wake_up_flag(hdev, nr)					\
19162306a36Sopenharmony_ci	do {								\
19262306a36Sopenharmony_ci		struct btintel_data *intel = hci_get_priv((hdev));	\
19362306a36Sopenharmony_ci		wake_up_bit(intel->flags, (nr));			\
19462306a36Sopenharmony_ci	} while (0)
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci#define btintel_get_flag(hdev)						\
19762306a36Sopenharmony_ci	(((struct btintel_data *)hci_get_priv(hdev))->flags)
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci#define btintel_test_flag(hdev, nr)	test_bit((nr), btintel_get_flag(hdev))
20062306a36Sopenharmony_ci#define btintel_test_and_clear_flag(hdev, nr) test_and_clear_bit((nr), btintel_get_flag(hdev))
20162306a36Sopenharmony_ci#define btintel_wait_on_flag_timeout(hdev, nr, m, to)			\
20262306a36Sopenharmony_ci		wait_on_bit_timeout(btintel_get_flag(hdev), (nr), m, to)
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_BT_INTEL)
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciint btintel_check_bdaddr(struct hci_dev *hdev);
20762306a36Sopenharmony_ciint btintel_enter_mfg(struct hci_dev *hdev);
20862306a36Sopenharmony_ciint btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched);
20962306a36Sopenharmony_ciint btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr);
21062306a36Sopenharmony_ciint btintel_set_diag(struct hci_dev *hdev, bool enable);
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ciint btintel_version_info(struct hci_dev *hdev, struct intel_version *ver);
21362306a36Sopenharmony_ciint btintel_load_ddc_config(struct hci_dev *hdev, const char *ddc_name);
21462306a36Sopenharmony_ciint btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug);
21562306a36Sopenharmony_ciint btintel_read_version(struct hci_dev *hdev, struct intel_version *ver);
21662306a36Sopenharmony_cistruct regmap *btintel_regmap_init(struct hci_dev *hdev, u16 opcode_read,
21762306a36Sopenharmony_ci				   u16 opcode_write);
21862306a36Sopenharmony_ciint btintel_send_intel_reset(struct hci_dev *hdev, u32 boot_param);
21962306a36Sopenharmony_ciint btintel_read_boot_params(struct hci_dev *hdev,
22062306a36Sopenharmony_ci			     struct intel_boot_params *params);
22162306a36Sopenharmony_ciint btintel_download_firmware(struct hci_dev *dev, struct intel_version *ver,
22262306a36Sopenharmony_ci			      const struct firmware *fw, u32 *boot_param);
22362306a36Sopenharmony_ciint btintel_configure_setup(struct hci_dev *hdev, const char *driver_name);
22462306a36Sopenharmony_ciint btintel_recv_event(struct hci_dev *hdev, struct sk_buff *skb);
22562306a36Sopenharmony_civoid btintel_bootup(struct hci_dev *hdev, const void *ptr, unsigned int len);
22662306a36Sopenharmony_civoid btintel_secure_send_result(struct hci_dev *hdev,
22762306a36Sopenharmony_ci				const void *ptr, unsigned int len);
22862306a36Sopenharmony_ciint btintel_set_quality_report(struct hci_dev *hdev, bool enable);
22962306a36Sopenharmony_ci#else
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistatic inline int btintel_check_bdaddr(struct hci_dev *hdev)
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci	return -EOPNOTSUPP;
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_cistatic inline int btintel_enter_mfg(struct hci_dev *hdev)
23762306a36Sopenharmony_ci{
23862306a36Sopenharmony_ci	return -EOPNOTSUPP;
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic inline int btintel_exit_mfg(struct hci_dev *hdev, bool reset, bool patched)
24262306a36Sopenharmony_ci{
24362306a36Sopenharmony_ci	return -EOPNOTSUPP;
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_cistatic inline int btintel_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
24762306a36Sopenharmony_ci{
24862306a36Sopenharmony_ci	return -EOPNOTSUPP;
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic inline int btintel_set_diag(struct hci_dev *hdev, bool enable)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	return -EOPNOTSUPP;
25462306a36Sopenharmony_ci}
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic inline int btintel_version_info(struct hci_dev *hdev,
25762306a36Sopenharmony_ci				       struct intel_version *ver)
25862306a36Sopenharmony_ci{
25962306a36Sopenharmony_ci	return -EOPNOTSUPP;
26062306a36Sopenharmony_ci}
26162306a36Sopenharmony_ci
26262306a36Sopenharmony_cistatic inline int btintel_load_ddc_config(struct hci_dev *hdev,
26362306a36Sopenharmony_ci					  const char *ddc_name)
26462306a36Sopenharmony_ci{
26562306a36Sopenharmony_ci	return -EOPNOTSUPP;
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic inline int btintel_set_event_mask_mfg(struct hci_dev *hdev, bool debug)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	return -EOPNOTSUPP;
27162306a36Sopenharmony_ci}
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_cistatic inline int btintel_read_version(struct hci_dev *hdev,
27462306a36Sopenharmony_ci				       struct intel_version *ver)
27562306a36Sopenharmony_ci{
27662306a36Sopenharmony_ci	return -EOPNOTSUPP;
27762306a36Sopenharmony_ci}
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_cistatic inline struct regmap *btintel_regmap_init(struct hci_dev *hdev,
28062306a36Sopenharmony_ci						 u16 opcode_read,
28162306a36Sopenharmony_ci						 u16 opcode_write)
28262306a36Sopenharmony_ci{
28362306a36Sopenharmony_ci	return ERR_PTR(-EINVAL);
28462306a36Sopenharmony_ci}
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_cistatic inline int btintel_send_intel_reset(struct hci_dev *hdev,
28762306a36Sopenharmony_ci					   u32 reset_param)
28862306a36Sopenharmony_ci{
28962306a36Sopenharmony_ci	return -EOPNOTSUPP;
29062306a36Sopenharmony_ci}
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_cistatic inline int btintel_read_boot_params(struct hci_dev *hdev,
29362306a36Sopenharmony_ci					   struct intel_boot_params *params)
29462306a36Sopenharmony_ci{
29562306a36Sopenharmony_ci	return -EOPNOTSUPP;
29662306a36Sopenharmony_ci}
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic inline int btintel_download_firmware(struct hci_dev *dev,
29962306a36Sopenharmony_ci					    const struct firmware *fw,
30062306a36Sopenharmony_ci					    u32 *boot_param)
30162306a36Sopenharmony_ci{
30262306a36Sopenharmony_ci	return -EOPNOTSUPP;
30362306a36Sopenharmony_ci}
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_cistatic inline int btintel_configure_setup(struct hci_dev *hdev,
30662306a36Sopenharmony_ci					  const char *driver_name)
30762306a36Sopenharmony_ci{
30862306a36Sopenharmony_ci	return -ENODEV;
30962306a36Sopenharmony_ci}
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_cistatic inline void btintel_bootup(struct hci_dev *hdev,
31262306a36Sopenharmony_ci				  const void *ptr, unsigned int len)
31362306a36Sopenharmony_ci{
31462306a36Sopenharmony_ci}
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_cistatic inline void btintel_secure_send_result(struct hci_dev *hdev,
31762306a36Sopenharmony_ci				const void *ptr, unsigned int len)
31862306a36Sopenharmony_ci{
31962306a36Sopenharmony_ci}
32062306a36Sopenharmony_ci
32162306a36Sopenharmony_cistatic inline int btintel_set_quality_report(struct hci_dev *hdev, bool enable)
32262306a36Sopenharmony_ci{
32362306a36Sopenharmony_ci	return -ENODEV;
32462306a36Sopenharmony_ci}
32562306a36Sopenharmony_ci#endif
326