1c942fddfSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2db33c77dSCarlo Caione /*
3db33c77dSCarlo Caione * Bluetooth support for Realtek devices
4db33c77dSCarlo Caione *
5db33c77dSCarlo Caione * Copyright (C) 2015 Endless Mobile, Inc.
6db33c77dSCarlo Caione */
7db33c77dSCarlo Caione
8db33c77dSCarlo Caione #define RTL_FRAG_LEN 252
9db33c77dSCarlo Caione
1026503ad2SMartin Blumenstingl #define rtl_dev_err(dev, fmt, ...) bt_dev_err(dev, "RTL: " fmt, ##__VA_ARGS__)
1126503ad2SMartin Blumenstingl #define rtl_dev_warn(dev, fmt, ...) bt_dev_warn(dev, "RTL: " fmt, ##__VA_ARGS__)
1226503ad2SMartin Blumenstingl #define rtl_dev_info(dev, fmt, ...) bt_dev_info(dev, "RTL: " fmt, ##__VA_ARGS__)
1326503ad2SMartin Blumenstingl #define rtl_dev_dbg(dev, fmt, ...) bt_dev_dbg(dev, "RTL: " fmt, ##__VA_ARGS__)
1426503ad2SMartin Blumenstingl
1526503ad2SMartin Blumenstingl struct btrtl_device_info;
1626503ad2SMartin Blumenstingl
17c0123cb6SVasily Khoruzhick struct rtl_chip_type_evt {
18c0123cb6SVasily Khoruzhick __u8 status;
19c0123cb6SVasily Khoruzhick __u8 type;
20c0123cb6SVasily Khoruzhick } __packed;
21c0123cb6SVasily Khoruzhick
22db33c77dSCarlo Caione struct rtl_download_cmd {
23db33c77dSCarlo Caione __u8 index;
24db33c77dSCarlo Caione __u8 data[RTL_FRAG_LEN];
25db33c77dSCarlo Caione } __packed;
26db33c77dSCarlo Caione
27db33c77dSCarlo Caione struct rtl_download_response {
28db33c77dSCarlo Caione __u8 status;
29db33c77dSCarlo Caione __u8 index;
30db33c77dSCarlo Caione } __packed;
31db33c77dSCarlo Caione
32db33c77dSCarlo Caione struct rtl_rom_version_evt {
33db33c77dSCarlo Caione __u8 status;
34db33c77dSCarlo Caione __u8 version;
35db33c77dSCarlo Caione } __packed;
36db33c77dSCarlo Caione
37db33c77dSCarlo Caione struct rtl_epatch_header {
38db33c77dSCarlo Caione __u8 signature[8];
39db33c77dSCarlo Caione __le32 fw_version;
40db33c77dSCarlo Caione __le16 num_patches;
41db33c77dSCarlo Caione } __packed;
42db33c77dSCarlo Caione
43b85b0ee1SMartin Blumenstingl struct rtl_vendor_config_entry {
44b85b0ee1SMartin Blumenstingl __le16 offset;
45b85b0ee1SMartin Blumenstingl __u8 len;
46a7e45454SGustavo A. R. Silva __u8 data[];
47b85b0ee1SMartin Blumenstingl } __packed;
48b85b0ee1SMartin Blumenstingl
49b85b0ee1SMartin Blumenstingl struct rtl_vendor_config {
50b85b0ee1SMartin Blumenstingl __le32 signature;
51b85b0ee1SMartin Blumenstingl __le16 total_len;
529a24ce5eSMax Chou __u8 entry[];
539a24ce5eSMax Chou } __packed;
549a24ce5eSMax Chou
559a24ce5eSMax Chou struct rtl_epatch_header_v2 {
569a24ce5eSMax Chou __u8 signature[8];
579a24ce5eSMax Chou __u8 fw_version[8];
589a24ce5eSMax Chou __le32 num_sections;
599a24ce5eSMax Chou } __packed;
609a24ce5eSMax Chou
619a24ce5eSMax Chou struct rtl_section {
629a24ce5eSMax Chou __le32 opcode;
639a24ce5eSMax Chou __le32 len;
649a24ce5eSMax Chou u8 data[];
659a24ce5eSMax Chou } __packed;
669a24ce5eSMax Chou
679a24ce5eSMax Chou struct rtl_section_hdr {
689a24ce5eSMax Chou __le16 num;
699a24ce5eSMax Chou __le16 reserved;
709a24ce5eSMax Chou } __packed;
719a24ce5eSMax Chou
729a24ce5eSMax Chou struct rtl_common_subsec {
739a24ce5eSMax Chou __u8 eco;
749a24ce5eSMax Chou __u8 prio;
759a24ce5eSMax Chou __u8 cb[2];
769a24ce5eSMax Chou __le32 len;
779a24ce5eSMax Chou __u8 data[];
789a24ce5eSMax Chou };
799a24ce5eSMax Chou
809a24ce5eSMax Chou struct rtl_sec_hdr {
819a24ce5eSMax Chou __u8 eco;
829a24ce5eSMax Chou __u8 prio;
839a24ce5eSMax Chou __u8 key_id;
849a24ce5eSMax Chou __u8 reserved;
859a24ce5eSMax Chou __le32 len;
869a24ce5eSMax Chou __u8 data[];
879a24ce5eSMax Chou } __packed;
889a24ce5eSMax Chou
899a24ce5eSMax Chou struct rtl_subsection {
909a24ce5eSMax Chou struct list_head list;
919a24ce5eSMax Chou u32 opcode;
929a24ce5eSMax Chou u32 len;
939a24ce5eSMax Chou u8 prio;
949a24ce5eSMax Chou u8 *data;
959a24ce5eSMax Chou };
969a24ce5eSMax Chou
979a24ce5eSMax Chou struct rtl_iovec {
989a24ce5eSMax Chou u8 *data;
999a24ce5eSMax Chou u32 len;
1009a24ce5eSMax Chou };
1019a24ce5eSMax Chou
1029a24ce5eSMax Chou struct rtl_vendor_cmd {
1039a24ce5eSMax Chou __u8 param[5];
104b85b0ee1SMartin Blumenstingl } __packed;
105b85b0ee1SMartin Blumenstingl
1065b355944SHilda Wu enum {
1075b355944SHilda Wu REALTEK_ALT6_CONTINUOUS_TX_CHIP,
1085b355944SHilda Wu
1095b355944SHilda Wu __REALTEK_NUM_FLAGS,
1105b355944SHilda Wu };
1115b355944SHilda Wu
112*044014ceSHilda Wu struct rtl_dump_info {
113*044014ceSHilda Wu const char *driver_name;
114*044014ceSHilda Wu char *controller;
115*044014ceSHilda Wu u32 fw_version;
116*044014ceSHilda Wu };
117*044014ceSHilda Wu
1185b355944SHilda Wu struct btrealtek_data {
1195b355944SHilda Wu DECLARE_BITMAP(flags, __REALTEK_NUM_FLAGS);
120*044014ceSHilda Wu
121*044014ceSHilda Wu struct rtl_dump_info rtl_dump;
1225b355944SHilda Wu };
1235b355944SHilda Wu
1245b355944SHilda Wu #define btrealtek_set_flag(hdev, nr) \
1255b355944SHilda Wu do { \
1265b355944SHilda Wu struct btrealtek_data *realtek = hci_get_priv((hdev)); \
1275b355944SHilda Wu set_bit((nr), realtek->flags); \
1285b355944SHilda Wu } while (0)
1295b355944SHilda Wu
1305b355944SHilda Wu #define btrealtek_get_flag(hdev) \
1315b355944SHilda Wu (((struct btrealtek_data *)hci_get_priv(hdev))->flags)
1325b355944SHilda Wu
1335b355944SHilda Wu #define btrealtek_test_flag(hdev, nr) test_bit((nr), btrealtek_get_flag(hdev))
1345b355944SHilda Wu
135db33c77dSCarlo Caione #if IS_ENABLED(CONFIG_BT_RTL)
136db33c77dSCarlo Caione
1371cc194caSHans de Goede struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
1381cc194caSHans de Goede const char *postfix);
13926503ad2SMartin Blumenstingl void btrtl_free(struct btrtl_device_info *btrtl_dev);
14026503ad2SMartin Blumenstingl int btrtl_download_firmware(struct hci_dev *hdev,
14126503ad2SMartin Blumenstingl struct btrtl_device_info *btrtl_dev);
1423011faa2SArchie Pusaka void btrtl_set_quirks(struct hci_dev *hdev,
1433011faa2SArchie Pusaka struct btrtl_device_info *btrtl_dev);
144db33c77dSCarlo Caione int btrtl_setup_realtek(struct hci_dev *hdev);
1457af3f558SJian-Hong Pan int btrtl_shutdown_realtek(struct hci_dev *hdev);
146b85b0ee1SMartin Blumenstingl int btrtl_get_uart_settings(struct hci_dev *hdev,
147b85b0ee1SMartin Blumenstingl struct btrtl_device_info *btrtl_dev,
148b85b0ee1SMartin Blumenstingl unsigned int *controller_baudrate,
149b85b0ee1SMartin Blumenstingl u32 *device_baudrate, bool *flow_control);
150*044014ceSHilda Wu void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name);
151db33c77dSCarlo Caione
152db33c77dSCarlo Caione #else
153db33c77dSCarlo Caione
btrtl_initialize(struct hci_dev * hdev,const char * postfix)1541cc194caSHans de Goede static inline struct btrtl_device_info *btrtl_initialize(struct hci_dev *hdev,
1551cc194caSHans de Goede const char *postfix)
15626503ad2SMartin Blumenstingl {
15726503ad2SMartin Blumenstingl return ERR_PTR(-EOPNOTSUPP);
15826503ad2SMartin Blumenstingl }
15926503ad2SMartin Blumenstingl
btrtl_free(struct btrtl_device_info * btrtl_dev)16026503ad2SMartin Blumenstingl static inline void btrtl_free(struct btrtl_device_info *btrtl_dev)
16126503ad2SMartin Blumenstingl {
16226503ad2SMartin Blumenstingl }
16326503ad2SMartin Blumenstingl
btrtl_download_firmware(struct hci_dev * hdev,struct btrtl_device_info * btrtl_dev)16426503ad2SMartin Blumenstingl static inline int btrtl_download_firmware(struct hci_dev *hdev,
16526503ad2SMartin Blumenstingl struct btrtl_device_info *btrtl_dev)
16626503ad2SMartin Blumenstingl {
16726503ad2SMartin Blumenstingl return -EOPNOTSUPP;
16826503ad2SMartin Blumenstingl }
16926503ad2SMartin Blumenstingl
btrtl_set_quirks(struct hci_dev * hdev,struct btrtl_device_info * btrtl_dev)1703011faa2SArchie Pusaka static inline void btrtl_set_quirks(struct hci_dev *hdev,
1713011faa2SArchie Pusaka struct btrtl_device_info *btrtl_dev)
1723011faa2SArchie Pusaka {
1733011faa2SArchie Pusaka }
1743011faa2SArchie Pusaka
btrtl_setup_realtek(struct hci_dev * hdev)175db33c77dSCarlo Caione static inline int btrtl_setup_realtek(struct hci_dev *hdev)
176db33c77dSCarlo Caione {
177db33c77dSCarlo Caione return -EOPNOTSUPP;
178db33c77dSCarlo Caione }
179db33c77dSCarlo Caione
btrtl_shutdown_realtek(struct hci_dev * hdev)1807af3f558SJian-Hong Pan static inline int btrtl_shutdown_realtek(struct hci_dev *hdev)
1817af3f558SJian-Hong Pan {
1827af3f558SJian-Hong Pan return -EOPNOTSUPP;
1837af3f558SJian-Hong Pan }
1847af3f558SJian-Hong Pan
btrtl_get_uart_settings(struct hci_dev * hdev,struct btrtl_device_info * btrtl_dev,unsigned int * controller_baudrate,u32 * device_baudrate,bool * flow_control)185b85b0ee1SMartin Blumenstingl static inline int btrtl_get_uart_settings(struct hci_dev *hdev,
186b85b0ee1SMartin Blumenstingl struct btrtl_device_info *btrtl_dev,
187b85b0ee1SMartin Blumenstingl unsigned int *controller_baudrate,
188b85b0ee1SMartin Blumenstingl u32 *device_baudrate,
189b85b0ee1SMartin Blumenstingl bool *flow_control)
190b85b0ee1SMartin Blumenstingl {
191b85b0ee1SMartin Blumenstingl return -ENOENT;
192b85b0ee1SMartin Blumenstingl }
193b85b0ee1SMartin Blumenstingl
btrtl_set_driver_name(struct hci_dev * hdev,const char * driver_name)194*044014ceSHilda Wu static inline void btrtl_set_driver_name(struct hci_dev *hdev, const char *driver_name)
195*044014ceSHilda Wu {
196*044014ceSHilda Wu }
197*044014ceSHilda Wu
198db33c77dSCarlo Caione #endif
199