xref: /freebsd/usr.sbin/bluetooth/iwmbtfw/iwmbt_hw.h (revision 06969db312022277729dd144e3655a90007306ef)
17f32f0e2SVladimir Kondratyev /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
37f32f0e2SVladimir Kondratyev  *
47f32f0e2SVladimir Kondratyev  * Copyright (c) 2019 Vladimir Kondratyev <wulf@FreeBSD.org>
5c1643cedSVladimir Kondratyev  * Copyright (c) 2023 Future Crew LLC.
67f32f0e2SVladimir Kondratyev  *
77f32f0e2SVladimir Kondratyev  * Redistribution and use in source and binary forms, with or without
87f32f0e2SVladimir Kondratyev  * modification, are permitted provided that the following conditions
97f32f0e2SVladimir Kondratyev  * are met:
107f32f0e2SVladimir Kondratyev  * 1. Redistributions of source code must retain the above copyright
117f32f0e2SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer.
127f32f0e2SVladimir Kondratyev  * 2. Redistributions in binary form must reproduce the above copyright
137f32f0e2SVladimir Kondratyev  *    notice, this list of conditions and the following disclaimer in the
147f32f0e2SVladimir Kondratyev  *    documentation and/or other materials provided with the distribution.
157f32f0e2SVladimir Kondratyev  *
167f32f0e2SVladimir Kondratyev  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
177f32f0e2SVladimir Kondratyev  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
187f32f0e2SVladimir Kondratyev  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
197f32f0e2SVladimir Kondratyev  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
207f32f0e2SVladimir Kondratyev  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
217f32f0e2SVladimir Kondratyev  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227f32f0e2SVladimir Kondratyev  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
237f32f0e2SVladimir Kondratyev  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
247f32f0e2SVladimir Kondratyev  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
257f32f0e2SVladimir Kondratyev  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267f32f0e2SVladimir Kondratyev  * SUCH DAMAGE.
277f32f0e2SVladimir Kondratyev  */
287f32f0e2SVladimir Kondratyev #ifndef	__IWMBT_HW_H__
297f32f0e2SVladimir Kondratyev #define	__IWMBT_HW_H__
307f32f0e2SVladimir Kondratyev 
317f32f0e2SVladimir Kondratyev /* USB control request (HCI command) structure */
327f32f0e2SVladimir Kondratyev struct iwmbt_hci_cmd {
337f32f0e2SVladimir Kondratyev 	uint16_t	opcode;
347f32f0e2SVladimir Kondratyev 	uint8_t		length;
357f32f0e2SVladimir Kondratyev 	uint8_t		data[];
367f32f0e2SVladimir Kondratyev } __attribute__ ((packed));
377f32f0e2SVladimir Kondratyev 
387f32f0e2SVladimir Kondratyev #define IWMBT_HCI_CMD_SIZE(cmd) \
397f32f0e2SVladimir Kondratyev 	((cmd)->length + offsetof(struct iwmbt_hci_cmd, data))
407f32f0e2SVladimir Kondratyev 
417f32f0e2SVladimir Kondratyev /* USB interrupt transfer HCI event header structure */
427f32f0e2SVladimir Kondratyev struct iwmbt_hci_evhdr {
437f32f0e2SVladimir Kondratyev 	uint8_t		event;
447f32f0e2SVladimir Kondratyev 	uint8_t		length;
457f32f0e2SVladimir Kondratyev } __attribute__ ((packed));
467f32f0e2SVladimir Kondratyev 
477f32f0e2SVladimir Kondratyev /* USB interrupt transfer (generic HCI event) structure */
487f32f0e2SVladimir Kondratyev struct iwmbt_hci_event {
497f32f0e2SVladimir Kondratyev 	struct iwmbt_hci_evhdr	header;
507f32f0e2SVladimir Kondratyev 	uint8_t			data[];
517f32f0e2SVladimir Kondratyev } __attribute__ ((packed));
527f32f0e2SVladimir Kondratyev 
537f32f0e2SVladimir Kondratyev /* USB interrupt transfer (HCI command completion event) structure */
547f32f0e2SVladimir Kondratyev struct iwmbt_hci_event_cmd_compl {
557f32f0e2SVladimir Kondratyev 	struct iwmbt_hci_evhdr	header;
567f32f0e2SVladimir Kondratyev 	uint8_t			numpkt;
577f32f0e2SVladimir Kondratyev 	uint16_t		opcode;
587f32f0e2SVladimir Kondratyev 	uint8_t			data[];
597f32f0e2SVladimir Kondratyev } __attribute__ ((packed));
607f32f0e2SVladimir Kondratyev 
61*06969db3SEygene Ryabinkin /*
62*06969db3SEygene Ryabinkin  * Manufacturer mode exit type: selects reset type,
63*06969db3SEygene Ryabinkin  * 0x00: simply exit manufacturer mode without a reset.
64*06969db3SEygene Ryabinkin  * 0x01: exit manufacturer mode with a reset and patches disabled
65*06969db3SEygene Ryabinkin  * 0x02: exit manufacturer mode with a reset and patches enabled
66*06969db3SEygene Ryabinkin  */
67*06969db3SEygene Ryabinkin enum iwmbt_mm_exit {
68*06969db3SEygene Ryabinkin 	IWMBT_MM_EXIT_ONLY = 0x00,
69*06969db3SEygene Ryabinkin 	IWMBT_MM_EXIT_COLD_RESET = 0x01,
70*06969db3SEygene Ryabinkin 	IWMBT_MM_EXIT_WARM_RESET = 0x02,
71*06969db3SEygene Ryabinkin };
72*06969db3SEygene Ryabinkin 
737f32f0e2SVladimir Kondratyev #define IWMBT_HCI_EVT_COMPL_SIZE(payload) \
747f32f0e2SVladimir Kondratyev 	(offsetof(struct iwmbt_hci_event_cmd_compl, data) + sizeof(payload))
75c1643cedSVladimir Kondratyev #define	IWMBT_HCI_EVENT_COMPL_HEAD_SIZE \
76c1643cedSVladimir Kondratyev 	(offsetof(struct iwmbt_hci_event_cmd_compl, data) - \
77c1643cedSVladimir Kondratyev 	 offsetof(struct iwmbt_hci_event_cmd_compl, numpkt))
787f32f0e2SVladimir Kondratyev 
797f32f0e2SVladimir Kondratyev #define	IWMBT_CONTROL_ENDPOINT_ADDR	0x00
807f32f0e2SVladimir Kondratyev #define	IWMBT_INTERRUPT_ENDPOINT_ADDR	0x81
817f32f0e2SVladimir Kondratyev #define	IWMBT_BULK_IN_ENDPOINT_ADDR	0x82
827f32f0e2SVladimir Kondratyev #define	IWMBT_BULK_OUT_ENDPOINT_ADDR	0x02
837f32f0e2SVladimir Kondratyev 
847f32f0e2SVladimir Kondratyev #define	IWMBT_HCI_MAX_CMD_SIZE		256
857f32f0e2SVladimir Kondratyev #define	IWMBT_HCI_MAX_EVENT_SIZE	16
867f32f0e2SVladimir Kondratyev 
87aa0b9384SVladimir Kondratyev #define	IWMBT_MSEC2TS(msec)				\
88aa0b9384SVladimir Kondratyev 	(struct timespec) {				\
89aa0b9384SVladimir Kondratyev 	    .tv_sec = (msec) / 1000,			\
90aa0b9384SVladimir Kondratyev 	    .tv_nsec = ((msec) % 1000) * 1000000	\
91aa0b9384SVladimir Kondratyev 	};
92aa0b9384SVladimir Kondratyev #define	IWMBT_TS2MSEC(ts)	((ts).tv_sec * 1000 + (ts).tv_nsec / 1000000)
937f32f0e2SVladimir Kondratyev #define	IWMBT_HCI_CMD_TIMEOUT		2000	/* ms */
947f32f0e2SVladimir Kondratyev #define	IWMBT_LOADCMPL_TIMEOUT		5000	/* ms */
957f32f0e2SVladimir Kondratyev 
96fe70d7b2SPhilippe Michaud-Boudreault extern	int iwmbt_patch_fwfile(struct libusb_device_handle *hdl,
97fe70d7b2SPhilippe Michaud-Boudreault 	    const struct iwmbt_firmware *fw);
98c1643cedSVladimir Kondratyev extern	int iwmbt_load_rsa_header(struct libusb_device_handle *hdl,
99c1643cedSVladimir Kondratyev 	    const struct iwmbt_firmware *fw);
100c1643cedSVladimir Kondratyev extern	int iwmbt_load_ecdsa_header(struct libusb_device_handle *hdl,
101c1643cedSVladimir Kondratyev 	    const struct iwmbt_firmware *fw);
1027f32f0e2SVladimir Kondratyev extern	int iwmbt_load_fwfile(struct libusb_device_handle *hdl,
103c1643cedSVladimir Kondratyev 	    const struct iwmbt_firmware *fw, uint32_t *boot_param, int offset);
104fe70d7b2SPhilippe Michaud-Boudreault extern	int iwmbt_enter_manufacturer(struct libusb_device_handle *hdl);
105fe70d7b2SPhilippe Michaud-Boudreault extern	int iwmbt_exit_manufacturer(struct libusb_device_handle *hdl,
106*06969db3SEygene Ryabinkin 	    enum iwmbt_mm_exit mode);
1077f32f0e2SVladimir Kondratyev extern	int iwmbt_get_version(struct libusb_device_handle *hdl,
1087f32f0e2SVladimir Kondratyev 	    struct iwmbt_version *version);
109c1643cedSVladimir Kondratyev extern	int iwmbt_get_version_tlv(struct libusb_device_handle *hdl,
110c1643cedSVladimir Kondratyev 	    struct iwmbt_version_tlv *version);
1117f32f0e2SVladimir Kondratyev extern	int iwmbt_get_boot_params(struct libusb_device_handle *hdl,
1127f32f0e2SVladimir Kondratyev 	    struct iwmbt_boot_params *params);
1137f32f0e2SVladimir Kondratyev extern	int iwmbt_intel_reset(struct libusb_device_handle *hdl,
1147f32f0e2SVladimir Kondratyev 	    uint32_t boot_param);
1157f32f0e2SVladimir Kondratyev extern	int iwmbt_load_ddc(struct libusb_device_handle *hdl,
1167f32f0e2SVladimir Kondratyev 	    const struct iwmbt_firmware *ddc);
1177f32f0e2SVladimir Kondratyev extern	int iwmbt_set_event_mask(struct libusb_device_handle *hdl);
1187f32f0e2SVladimir Kondratyev 
1197f32f0e2SVladimir Kondratyev #endif
120