@@ -3128,6 +3128,12 @@ static int btusb_shutdown_intel_new(struct hci_dev *hdev)
31283128#define FIRMWARE_MT7668 "mediatek/mt7668pr2h.bin"
31293129
31303130#define HCI_WMT_MAX_EVENT_SIZE 64
3131+ /* It is for mt79xx download rom patch*/
3132+ #define MTK_FW_ROM_PATCH_HEADER_SIZE 32
3133+ #define MTK_FW_ROM_PATCH_GD_SIZE 64
3134+ #define MTK_FW_ROM_PATCH_SEC_MAP_SIZE 64
3135+ #define MTK_SEC_MAP_COMMON_SIZE 12
3136+ #define MTK_SEC_MAP_NEED_SEND_SIZE 52
31313137
31323138enum {
31333139 BTMTK_WMT_PATCH_DWNLD = 0x1 ,
@@ -3184,6 +3190,40 @@ struct btmtk_hci_wmt_params {
31843190 u32 * status ;
31853191};
31863192
3193+ struct btmtk_patch_header {
3194+ u8 datetime [16 ];
3195+ u8 platform [4 ];
3196+ __le16 hwver ;
3197+ __le16 swver ;
3198+ __le32 magicnum ;
3199+ } __packed ;
3200+
3201+ struct btmtk_global_desc {
3202+ __le32 patch_ver ;
3203+ __le32 sub_sys ;
3204+ __le32 feature_opt ;
3205+ __le32 section_num ;
3206+ } __packed ;
3207+
3208+ struct btmtk_section_map {
3209+ __le32 sectype ;
3210+ __le32 secoffset ;
3211+ __le32 secsize ;
3212+ union {
3213+ __le32 u4SecSpec [13 ];
3214+ struct {
3215+ __le32 dlAddr ;
3216+ __le32 dlsize ;
3217+ __le32 seckeyidx ;
3218+ __le32 alignlen ;
3219+ __le32 sectype ;
3220+ __le32 dlmodecrctype ;
3221+ __le32 crc ;
3222+ __le32 reserved [6 ];
3223+ } bin_info_spec ;
3224+ };
3225+ } __packed ;
3226+
31873227static void btusb_mtk_wmt_recv (struct urb * urb )
31883228{
31893229 struct hci_dev * hdev = urb -> context ;
@@ -3407,6 +3447,14 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
34073447 else
34083448 status = BTMTK_WMT_ON_UNDONE ;
34093449 break ;
3450+ case BTMTK_WMT_PATCH_DWNLD :
3451+ if (wmt_evt -> whdr .flag == 2 )
3452+ status = BTMTK_WMT_PATCH_DONE ;
3453+ else if (wmt_evt -> whdr .flag == 1 )
3454+ status = BTMTK_WMT_PATCH_PROGRESS ;
3455+ else
3456+ status = BTMTK_WMT_PATCH_UNDONE ;
3457+ break ;
34103458 }
34113459
34123460 if (wmt_params -> status )
@@ -3419,6 +3467,122 @@ static int btusb_mtk_hci_wmt_sync(struct hci_dev *hdev,
34193467 return err ;
34203468}
34213469
3470+ static int btusb_mtk_setup_firmware_79xx (struct hci_dev * hdev , const char * fwname )
3471+ {
3472+ struct btmtk_hci_wmt_params wmt_params ;
3473+ struct btmtk_patch_header * patchhdr = NULL ;
3474+ struct btmtk_global_desc * globaldesc = NULL ;
3475+ struct btmtk_section_map * sectionmap ;
3476+ const struct firmware * fw ;
3477+ const u8 * fw_ptr ;
3478+ const u8 * fw_bin_ptr ;
3479+ size_t fw_size ;
3480+ int err , dlen , i , status ;
3481+ u8 flag , first_block , retry ;
3482+ u32 section_num , dl_size , section_offset ;
3483+ u8 cmd [64 ];
3484+
3485+ err = request_firmware (& fw , fwname , & hdev -> dev );
3486+ if (err < 0 ) {
3487+ bt_dev_err (hdev , "Failed to load firmware file (%d)" , err );
3488+ return err ;
3489+ }
3490+
3491+ fw_ptr = fw -> data ;
3492+ fw_bin_ptr = fw_ptr ;
3493+ fw_size = fw -> size ;
3494+ patchhdr = (struct btmtk_patch_header * )fw_ptr ;
3495+ globaldesc = (struct btmtk_global_desc * )(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE );
3496+ section_num = globaldesc -> section_num ;
3497+
3498+ for (i = 0 ; i < section_num ; i ++ ) {
3499+ first_block = 1 ;
3500+ fw_ptr = fw_bin_ptr ;
3501+ sectionmap = (struct btmtk_section_map * )(fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
3502+ MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i );
3503+
3504+ section_offset = sectionmap -> secoffset ;
3505+ dl_size = sectionmap -> bin_info_spec .dlsize ;
3506+
3507+ if (dl_size > 0 ) {
3508+ retry = 20 ;
3509+ while (retry > 0 ) {
3510+ cmd [0 ] = 0 ; /* 0 means legacy dl mode. */
3511+ memcpy (cmd + 1 ,
3512+ fw_ptr + MTK_FW_ROM_PATCH_HEADER_SIZE +
3513+ MTK_FW_ROM_PATCH_GD_SIZE + MTK_FW_ROM_PATCH_SEC_MAP_SIZE * i +
3514+ MTK_SEC_MAP_COMMON_SIZE ,
3515+ MTK_SEC_MAP_NEED_SEND_SIZE + 1 );
3516+
3517+ wmt_params .op = BTMTK_WMT_PATCH_DWNLD ;
3518+ wmt_params .status = & status ;
3519+ wmt_params .flag = 0 ;
3520+ wmt_params .dlen = MTK_SEC_MAP_NEED_SEND_SIZE + 1 ;
3521+ wmt_params .data = & cmd ;
3522+
3523+ err = btusb_mtk_hci_wmt_sync (hdev , & wmt_params );
3524+ if (err < 0 ) {
3525+ bt_dev_err (hdev , "Failed to send wmt patch dwnld (%d)" ,
3526+ err );
3527+ goto err_release_fw ;
3528+ }
3529+
3530+ if (status == BTMTK_WMT_PATCH_UNDONE ) {
3531+ break ;
3532+ } else if (status == BTMTK_WMT_PATCH_PROGRESS ) {
3533+ msleep (100 );
3534+ retry -- ;
3535+ } else if (status == BTMTK_WMT_PATCH_DONE ) {
3536+ goto next_section ;
3537+ } else {
3538+ bt_dev_err (hdev , "Failed wmt patch dwnld status (%d)" ,
3539+ status );
3540+ goto err_release_fw ;
3541+ }
3542+ }
3543+
3544+ fw_ptr += section_offset ;
3545+ wmt_params .op = BTMTK_WMT_PATCH_DWNLD ;
3546+ wmt_params .status = NULL ;
3547+
3548+ while (dl_size > 0 ) {
3549+ dlen = min_t (int , 250 , dl_size );
3550+ if (first_block == 1 ) {
3551+ flag = 1 ;
3552+ first_block = 0 ;
3553+ } else if (dl_size - dlen <= 0 ) {
3554+ flag = 3 ;
3555+ } else {
3556+ flag = 2 ;
3557+ }
3558+
3559+ wmt_params .flag = flag ;
3560+ wmt_params .dlen = dlen ;
3561+ wmt_params .data = fw_ptr ;
3562+
3563+ err = btusb_mtk_hci_wmt_sync (hdev , & wmt_params );
3564+ if (err < 0 ) {
3565+ bt_dev_err (hdev , "Failed to send wmt patch dwnld (%d)" ,
3566+ err );
3567+ goto err_release_fw ;
3568+ }
3569+
3570+ dl_size -= dlen ;
3571+ fw_ptr += dlen ;
3572+ }
3573+ }
3574+ next_section :
3575+ continue ;
3576+ }
3577+ /* Wait a few moments for firmware activation done */
3578+ usleep_range (100000 , 120000 );
3579+
3580+ err_release_fw :
3581+ release_firmware (fw );
3582+
3583+ return err ;
3584+ }
3585+
34223586static int btusb_mtk_setup_firmware (struct hci_dev * hdev , const char * fwname )
34233587{
34243588 struct btmtk_hci_wmt_params wmt_params ;
@@ -3573,6 +3737,8 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
35733737 const char * fwname ;
35743738 int err , status ;
35753739 u32 dev_id ;
3740+ char fw_bin_name [64 ];
3741+ u32 fw_version ;
35763742 u8 param ;
35773743
35783744 calltime = ktime_get ();
@@ -3583,13 +3749,46 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
35833749 return err ;
35843750 }
35853751
3752+ if (!dev_id ) {
3753+ err = btusb_mtk_id_get (data , 0x70010200 , & dev_id );
3754+ if (err < 0 ) {
3755+ bt_dev_err (hdev , "Failed to get device id (%d)" , err );
3756+ return err ;
3757+ }
3758+ err = btusb_mtk_id_get (data , 0x80021004 , & fw_version );
3759+ if (err < 0 ) {
3760+ bt_dev_err (hdev , "Failed to get fw version (%d)" , err );
3761+ return err ;
3762+ }
3763+ }
3764+
35863765 switch (dev_id ) {
35873766 case 0x7663 :
35883767 fwname = FIRMWARE_MT7663 ;
35893768 break ;
35903769 case 0x7668 :
35913770 fwname = FIRMWARE_MT7668 ;
35923771 break ;
3772+ case 0x7961 :
3773+ snprintf (fw_bin_name , sizeof (fw_bin_name ),
3774+ "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin" ,
3775+ dev_id & 0xffff , (fw_version & 0xff ) + 1 );
3776+ err = btusb_mtk_setup_firmware_79xx (hdev , fw_bin_name );
3777+
3778+ /* Enable Bluetooth protocol */
3779+ param = 1 ;
3780+ wmt_params .op = BTMTK_WMT_FUNC_CTRL ;
3781+ wmt_params .flag = 0 ;
3782+ wmt_params .dlen = sizeof (param );
3783+ wmt_params .data = & param ;
3784+ wmt_params .status = NULL ;
3785+
3786+ err = btusb_mtk_hci_wmt_sync (hdev , & wmt_params );
3787+ if (err < 0 ) {
3788+ bt_dev_err (hdev , "Failed to send wmt func ctrl (%d)" , err );
3789+ return err ;
3790+ }
3791+ goto done ;
35933792 default :
35943793 bt_dev_err (hdev , "Unsupported support hardware variant (%08x)" ,
35953794 dev_id );
@@ -3667,6 +3866,7 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
36673866 }
36683867 kfree_skb (skb );
36693868
3869+ done :
36703870 rettime = ktime_get ();
36713871 delta = ktime_sub (rettime , calltime );
36723872 duration = (unsigned long long )ktime_to_ns (delta ) >> 10 ;
0 commit comments