Merge tag 'pull-work.fd-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / drivers / bluetooth / btmtk.c
1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2021 MediaTek Inc.
3  *
4  */
5 #include <linux/module.h>
6 #include <linux/firmware.h>
7
8 #include <net/bluetooth/bluetooth.h>
9 #include <net/bluetooth/hci_core.h>
10
11 #include "btmtk.h"
12
13 #define VERSION "0.1"
14
15 /* It is for mt79xx download rom patch*/
16 #define MTK_FW_ROM_PATCH_HEADER_SIZE    32
17 #define MTK_FW_ROM_PATCH_GD_SIZE        64
18 #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE   64
19 #define MTK_SEC_MAP_COMMON_SIZE 12
20 #define MTK_SEC_MAP_NEED_SEND_SIZE      52
21
22 struct btmtk_patch_header {
23         u8 datetime[16];
24         u8 platform[4];
25         __le16 hwver;
26         __le16 swver;
27         __le32 magicnum;
28 } __packed;
29
30 struct btmtk_global_desc {
31         __le32 patch_ver;
32         __le32 sub_sys;
33         __le32 feature_opt;
34         __le32 section_num;
35 } __packed;
36
37 struct btmtk_section_map {
38         __le32 sectype;
39         __le32 secoffset;
40         __le32 secsize;
41         union {
42                 __le32 u4SecSpec[13];
43                 struct {
44                         __le32 dlAddr;
45                         __le32 dlsize;
46                         __le32 seckeyidx;
47                         __le32 alignlen;
48                         __le32 sectype;
49                         __le32 dlmodecrctype;
50                         __le32 crc;
51                         __le32 reserved[6];
52                 } bin_info_spec;
53         };
54 } __packed;
55
56 int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
57                               wmt_cmd_sync_func_t wmt_cmd_sync)
58 {
59         struct btmtk_hci_wmt_params wmt_params;
60         struct btmtk_global_desc *globaldesc = NULL;
61         struct btmtk_section_map *sectionmap;
62         const struct firmware *fw;
63         const u8 *fw_ptr;
64         const u8 *fw_bin_ptr;
65         int err, dlen, i, status;
66         u8 flag, first_block, retry;
67         u32 section_num, dl_size, section_offset;
68         u8 cmd[64];
69
70         err = request_firmware(&fw, fwname, &hdev->dev);
71         if (err < 0) {
72                 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
73                 return err;
74         }
75
76         fw_ptr = fw->data;
77         fw_bin_ptr = fw_ptr;
78         globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
79         section_num = le32_to_cpu(globaldesc->section_num);
80
81         for (i = 0; i < section_num; i++) {
82                 first_block = 1;
83                 fw_ptr = fw_bin_ptr;
84                 sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
85                               MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
86
87                 section_offset = le32_to_cpu(sectionmap->secoffset);
88                 dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
89
90                 if (dl_size > 0) {
91                         retry = 20;
92                         while (retry > 0) {
93                                 cmd[0] = 0; /* 0 means legacy dl mode. */
94                                 memcpy(cmd + 1,
95                                        fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
96                                        MTK_FW_ROM_PATCH_GD_SIZE +
97                                        MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
98                                        MTK_SEC_MAP_COMMON_SIZE,
99                                        MTK_SEC_MAP_NEED_SEND_SIZE + 1);
100
101                                 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
102                                 wmt_params.status = &status;
103                                 wmt_params.flag = 0;
104                                 wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
105                                 wmt_params.data = &cmd;
106
107                                 err = wmt_cmd_sync(hdev, &wmt_params);
108                                 if (err < 0) {
109                                         bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
110                                                    err);
111                                         goto err_release_fw;
112                                 }
113
114                                 if (status == BTMTK_WMT_PATCH_UNDONE) {
115                                         break;
116                                 } else if (status == BTMTK_WMT_PATCH_PROGRESS) {
117                                         msleep(100);
118                                         retry--;
119                                 } else if (status == BTMTK_WMT_PATCH_DONE) {
120                                         goto next_section;
121                                 } else {
122                                         bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
123                                                    status);
124                                         err = -EIO;
125                                         goto err_release_fw;
126                                 }
127                         }
128
129                         fw_ptr += section_offset;
130                         wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
131                         wmt_params.status = NULL;
132
133                         while (dl_size > 0) {
134                                 dlen = min_t(int, 250, dl_size);
135                                 if (first_block == 1) {
136                                         flag = 1;
137                                         first_block = 0;
138                                 } else if (dl_size - dlen <= 0) {
139                                         flag = 3;
140                                 } else {
141                                         flag = 2;
142                                 }
143
144                                 wmt_params.flag = flag;
145                                 wmt_params.dlen = dlen;
146                                 wmt_params.data = fw_ptr;
147
148                                 err = wmt_cmd_sync(hdev, &wmt_params);
149                                 if (err < 0) {
150                                         bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
151                                                    err);
152                                         goto err_release_fw;
153                                 }
154
155                                 dl_size -= dlen;
156                                 fw_ptr += dlen;
157                         }
158                 }
159 next_section:
160                 continue;
161         }
162         /* Wait a few moments for firmware activation done */
163         usleep_range(100000, 120000);
164
165 err_release_fw:
166         release_firmware(fw);
167
168         return err;
169 }
170 EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
171
172 int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
173                          wmt_cmd_sync_func_t wmt_cmd_sync)
174 {
175         struct btmtk_hci_wmt_params wmt_params;
176         const struct firmware *fw;
177         const u8 *fw_ptr;
178         size_t fw_size;
179         int err, dlen;
180         u8 flag, param;
181
182         err = request_firmware(&fw, fwname, &hdev->dev);
183         if (err < 0) {
184                 bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
185                 return err;
186         }
187
188         /* Power on data RAM the firmware relies on. */
189         param = 1;
190         wmt_params.op = BTMTK_WMT_FUNC_CTRL;
191         wmt_params.flag = 3;
192         wmt_params.dlen = sizeof(param);
193         wmt_params.data = &param;
194         wmt_params.status = NULL;
195
196         err = wmt_cmd_sync(hdev, &wmt_params);
197         if (err < 0) {
198                 bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
199                 goto err_release_fw;
200         }
201
202         fw_ptr = fw->data;
203         fw_size = fw->size;
204
205         /* The size of patch header is 30 bytes, should be skip */
206         if (fw_size < 30) {
207                 err = -EINVAL;
208                 goto err_release_fw;
209         }
210
211         fw_size -= 30;
212         fw_ptr += 30;
213         flag = 1;
214
215         wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
216         wmt_params.status = NULL;
217
218         while (fw_size > 0) {
219                 dlen = min_t(int, 250, fw_size);
220
221                 /* Tell device the position in sequence */
222                 if (fw_size - dlen <= 0)
223                         flag = 3;
224                 else if (fw_size < fw->size - 30)
225                         flag = 2;
226
227                 wmt_params.flag = flag;
228                 wmt_params.dlen = dlen;
229                 wmt_params.data = fw_ptr;
230
231                 err = wmt_cmd_sync(hdev, &wmt_params);
232                 if (err < 0) {
233                         bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
234                                    err);
235                         goto err_release_fw;
236                 }
237
238                 fw_size -= dlen;
239                 fw_ptr += dlen;
240         }
241
242         wmt_params.op = BTMTK_WMT_RST;
243         wmt_params.flag = 4;
244         wmt_params.dlen = 0;
245         wmt_params.data = NULL;
246         wmt_params.status = NULL;
247
248         /* Activate funciton the firmware providing to */
249         err = wmt_cmd_sync(hdev, &wmt_params);
250         if (err < 0) {
251                 bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
252                 goto err_release_fw;
253         }
254
255         /* Wait a few moments for firmware activation done */
256         usleep_range(10000, 12000);
257
258 err_release_fw:
259         release_firmware(fw);
260
261         return err;
262 }
263 EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
264
265 int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
266 {
267         struct sk_buff *skb;
268         long ret;
269
270         skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
271         if (IS_ERR(skb)) {
272                 ret = PTR_ERR(skb);
273                 bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
274                            ret);
275                 return ret;
276         }
277         kfree_skb(skb);
278
279         return 0;
280 }
281 EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
282
283 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
284 MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
285 MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
286 MODULE_VERSION(VERSION);
287 MODULE_LICENSE("GPL");
288 MODULE_FIRMWARE(FIRMWARE_MT7622);
289 MODULE_FIRMWARE(FIRMWARE_MT7663);
290 MODULE_FIRMWARE(FIRMWARE_MT7668);
291 MODULE_FIRMWARE(FIRMWARE_MT7961);