Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2021 MediaTek Inc.
0003  *
0004  */
0005 #include <linux/module.h>
0006 #include <linux/firmware.h>
0007 
0008 #include <net/bluetooth/bluetooth.h>
0009 #include <net/bluetooth/hci_core.h>
0010 
0011 #include "btmtk.h"
0012 
0013 #define VERSION "0.1"
0014 
0015 /* It is for mt79xx download rom patch*/
0016 #define MTK_FW_ROM_PATCH_HEADER_SIZE    32
0017 #define MTK_FW_ROM_PATCH_GD_SIZE    64
0018 #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE   64
0019 #define MTK_SEC_MAP_COMMON_SIZE 12
0020 #define MTK_SEC_MAP_NEED_SEND_SIZE  52
0021 
0022 struct btmtk_patch_header {
0023     u8 datetime[16];
0024     u8 platform[4];
0025     __le16 hwver;
0026     __le16 swver;
0027     __le32 magicnum;
0028 } __packed;
0029 
0030 struct btmtk_global_desc {
0031     __le32 patch_ver;
0032     __le32 sub_sys;
0033     __le32 feature_opt;
0034     __le32 section_num;
0035 } __packed;
0036 
0037 struct btmtk_section_map {
0038     __le32 sectype;
0039     __le32 secoffset;
0040     __le32 secsize;
0041     union {
0042         __le32 u4SecSpec[13];
0043         struct {
0044             __le32 dlAddr;
0045             __le32 dlsize;
0046             __le32 seckeyidx;
0047             __le32 alignlen;
0048             __le32 sectype;
0049             __le32 dlmodecrctype;
0050             __le32 crc;
0051             __le32 reserved[6];
0052         } bin_info_spec;
0053     };
0054 } __packed;
0055 
0056 int btmtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwname,
0057                   wmt_cmd_sync_func_t wmt_cmd_sync)
0058 {
0059     struct btmtk_hci_wmt_params wmt_params;
0060     struct btmtk_global_desc *globaldesc = NULL;
0061     struct btmtk_section_map *sectionmap;
0062     const struct firmware *fw;
0063     const u8 *fw_ptr;
0064     const u8 *fw_bin_ptr;
0065     int err, dlen, i, status;
0066     u8 flag, first_block, retry;
0067     u32 section_num, dl_size, section_offset;
0068     u8 cmd[64];
0069 
0070     err = request_firmware(&fw, fwname, &hdev->dev);
0071     if (err < 0) {
0072         bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
0073         return err;
0074     }
0075 
0076     fw_ptr = fw->data;
0077     fw_bin_ptr = fw_ptr;
0078     globaldesc = (struct btmtk_global_desc *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE);
0079     section_num = le32_to_cpu(globaldesc->section_num);
0080 
0081     for (i = 0; i < section_num; i++) {
0082         first_block = 1;
0083         fw_ptr = fw_bin_ptr;
0084         sectionmap = (struct btmtk_section_map *)(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
0085                   MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i);
0086 
0087         section_offset = le32_to_cpu(sectionmap->secoffset);
0088         dl_size = le32_to_cpu(sectionmap->bin_info_spec.dlsize);
0089 
0090         if (dl_size > 0) {
0091             retry = 20;
0092             while (retry > 0) {
0093                 cmd[0] = 0; /* 0 means legacy dl mode. */
0094                 memcpy(cmd + 1,
0095                        fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
0096                        MTK_FW_ROM_PATCH_GD_SIZE +
0097                        MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
0098                        MTK_SEC_MAP_COMMON_SIZE,
0099                        MTK_SEC_MAP_NEED_SEND_SIZE + 1);
0100 
0101                 wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0102                 wmt_params.status = &status;
0103                 wmt_params.flag = 0;
0104                 wmt_params.dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1;
0105                 wmt_params.data = &cmd;
0106 
0107                 err = wmt_cmd_sync(hdev, &wmt_params);
0108                 if (err < 0) {
0109                     bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0110                            err);
0111                     goto err_release_fw;
0112                 }
0113 
0114                 if (status == BTMTK_WMT_PATCH_UNDONE) {
0115                     break;
0116                 } else if (status == BTMTK_WMT_PATCH_PROGRESS) {
0117                     msleep(100);
0118                     retry--;
0119                 } else if (status == BTMTK_WMT_PATCH_DONE) {
0120                     goto next_section;
0121                 } else {
0122                     bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)",
0123                            status);
0124                     err = -EIO;
0125                     goto err_release_fw;
0126                 }
0127             }
0128 
0129             fw_ptr += section_offset;
0130             wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0131             wmt_params.status = NULL;
0132 
0133             while (dl_size > 0) {
0134                 dlen = min_t(int, 250, dl_size);
0135                 if (first_block == 1) {
0136                     flag = 1;
0137                     first_block = 0;
0138                 } else if (dl_size - dlen <= 0) {
0139                     flag = 3;
0140                 } else {
0141                     flag = 2;
0142                 }
0143 
0144                 wmt_params.flag = flag;
0145                 wmt_params.dlen = dlen;
0146                 wmt_params.data = fw_ptr;
0147 
0148                 err = wmt_cmd_sync(hdev, &wmt_params);
0149                 if (err < 0) {
0150                     bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0151                            err);
0152                     goto err_release_fw;
0153                 }
0154 
0155                 dl_size -= dlen;
0156                 fw_ptr += dlen;
0157             }
0158         }
0159 next_section:
0160         continue;
0161     }
0162     /* Wait a few moments for firmware activation done */
0163     usleep_range(100000, 120000);
0164 
0165 err_release_fw:
0166     release_firmware(fw);
0167 
0168     return err;
0169 }
0170 EXPORT_SYMBOL_GPL(btmtk_setup_firmware_79xx);
0171 
0172 int btmtk_setup_firmware(struct hci_dev *hdev, const char *fwname,
0173              wmt_cmd_sync_func_t wmt_cmd_sync)
0174 {
0175     struct btmtk_hci_wmt_params wmt_params;
0176     const struct firmware *fw;
0177     const u8 *fw_ptr;
0178     size_t fw_size;
0179     int err, dlen;
0180     u8 flag, param;
0181 
0182     err = request_firmware(&fw, fwname, &hdev->dev);
0183     if (err < 0) {
0184         bt_dev_err(hdev, "Failed to load firmware file (%d)", err);
0185         return err;
0186     }
0187 
0188     /* Power on data RAM the firmware relies on. */
0189     param = 1;
0190     wmt_params.op = BTMTK_WMT_FUNC_CTRL;
0191     wmt_params.flag = 3;
0192     wmt_params.dlen = sizeof(param);
0193     wmt_params.data = &param;
0194     wmt_params.status = NULL;
0195 
0196     err = wmt_cmd_sync(hdev, &wmt_params);
0197     if (err < 0) {
0198         bt_dev_err(hdev, "Failed to power on data RAM (%d)", err);
0199         goto err_release_fw;
0200     }
0201 
0202     fw_ptr = fw->data;
0203     fw_size = fw->size;
0204 
0205     /* The size of patch header is 30 bytes, should be skip */
0206     if (fw_size < 30) {
0207         err = -EINVAL;
0208         goto err_release_fw;
0209     }
0210 
0211     fw_size -= 30;
0212     fw_ptr += 30;
0213     flag = 1;
0214 
0215     wmt_params.op = BTMTK_WMT_PATCH_DWNLD;
0216     wmt_params.status = NULL;
0217 
0218     while (fw_size > 0) {
0219         dlen = min_t(int, 250, fw_size);
0220 
0221         /* Tell device the position in sequence */
0222         if (fw_size - dlen <= 0)
0223             flag = 3;
0224         else if (fw_size < fw->size - 30)
0225             flag = 2;
0226 
0227         wmt_params.flag = flag;
0228         wmt_params.dlen = dlen;
0229         wmt_params.data = fw_ptr;
0230 
0231         err = wmt_cmd_sync(hdev, &wmt_params);
0232         if (err < 0) {
0233             bt_dev_err(hdev, "Failed to send wmt patch dwnld (%d)",
0234                    err);
0235             goto err_release_fw;
0236         }
0237 
0238         fw_size -= dlen;
0239         fw_ptr += dlen;
0240     }
0241 
0242     wmt_params.op = BTMTK_WMT_RST;
0243     wmt_params.flag = 4;
0244     wmt_params.dlen = 0;
0245     wmt_params.data = NULL;
0246     wmt_params.status = NULL;
0247 
0248     /* Activate funciton the firmware providing to */
0249     err = wmt_cmd_sync(hdev, &wmt_params);
0250     if (err < 0) {
0251         bt_dev_err(hdev, "Failed to send wmt rst (%d)", err);
0252         goto err_release_fw;
0253     }
0254 
0255     /* Wait a few moments for firmware activation done */
0256     usleep_range(10000, 12000);
0257 
0258 err_release_fw:
0259     release_firmware(fw);
0260 
0261     return err;
0262 }
0263 EXPORT_SYMBOL_GPL(btmtk_setup_firmware);
0264 
0265 int btmtk_set_bdaddr(struct hci_dev *hdev, const bdaddr_t *bdaddr)
0266 {
0267     struct sk_buff *skb;
0268     long ret;
0269 
0270     skb = __hci_cmd_sync(hdev, 0xfc1a, 6, bdaddr, HCI_INIT_TIMEOUT);
0271     if (IS_ERR(skb)) {
0272         ret = PTR_ERR(skb);
0273         bt_dev_err(hdev, "changing Mediatek device address failed (%ld)",
0274                ret);
0275         return ret;
0276     }
0277     kfree_skb(skb);
0278 
0279     return 0;
0280 }
0281 EXPORT_SYMBOL_GPL(btmtk_set_bdaddr);
0282 
0283 MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
0284 MODULE_AUTHOR("Mark Chen <mark-yw.chen@mediatek.com>");
0285 MODULE_DESCRIPTION("Bluetooth support for MediaTek devices ver " VERSION);
0286 MODULE_VERSION(VERSION);
0287 MODULE_LICENSE("GPL");
0288 MODULE_FIRMWARE(FIRMWARE_MT7622);
0289 MODULE_FIRMWARE(FIRMWARE_MT7663);
0290 MODULE_FIRMWARE(FIRMWARE_MT7668);
0291 MODULE_FIRMWARE(FIRMWARE_MT7961);