@@ -10498,3 +10498,224 @@ int ath12k_wmi_send_vdev_set_tpc_power(struct ath12k *ar,
10498
10498
10499
10499
return 0 ;
10500
10500
}
10501
+
10502
+ static int
10503
+ ath12k_wmi_fill_disallowed_bmap (struct ath12k_base * ab ,
10504
+ struct wmi_disallowed_mlo_mode_bitmap_params * dislw_bmap ,
10505
+ struct wmi_mlo_link_set_active_arg * arg )
10506
+ {
10507
+ struct wmi_ml_disallow_mode_bmap_arg * dislw_bmap_arg ;
10508
+ u8 i ;
10509
+
10510
+ if (arg -> num_disallow_mode_comb >
10511
+ ARRAY_SIZE (arg -> disallow_bmap )) {
10512
+ ath12k_warn (ab , "invalid num_disallow_mode_comb: %d" ,
10513
+ arg -> num_disallow_mode_comb );
10514
+ return - EINVAL ;
10515
+ }
10516
+
10517
+ dislw_bmap_arg = & arg -> disallow_bmap [0 ];
10518
+ for (i = 0 ; i < arg -> num_disallow_mode_comb ; i ++ ) {
10519
+ dislw_bmap -> tlv_header =
10520
+ ath12k_wmi_tlv_cmd_hdr (0 , sizeof (* dislw_bmap ));
10521
+ dislw_bmap -> disallowed_mode_bitmap =
10522
+ cpu_to_le32 (dislw_bmap_arg -> disallowed_mode );
10523
+ dislw_bmap -> ieee_link_id_comb =
10524
+ le32_encode_bits (dislw_bmap_arg -> ieee_link_id [0 ],
10525
+ WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_1 ) |
10526
+ le32_encode_bits (dislw_bmap_arg -> ieee_link_id [1 ],
10527
+ WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_2 ) |
10528
+ le32_encode_bits (dislw_bmap_arg -> ieee_link_id [2 ],
10529
+ WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_3 ) |
10530
+ le32_encode_bits (dislw_bmap_arg -> ieee_link_id [3 ],
10531
+ WMI_DISALW_MLO_MODE_BMAP_IEEE_LINK_ID_COMB_4 );
10532
+
10533
+ ath12k_dbg (ab , ATH12K_DBG_WMI ,
10534
+ "entry %d disallowed_mode %d ieee_link_id_comb 0x%x" ,
10535
+ i , dislw_bmap_arg -> disallowed_mode ,
10536
+ dislw_bmap_arg -> ieee_link_id_comb );
10537
+ dislw_bmap ++ ;
10538
+ dislw_bmap_arg ++ ;
10539
+ }
10540
+
10541
+ return 0 ;
10542
+ }
10543
+
10544
+ int ath12k_wmi_send_mlo_link_set_active_cmd (struct ath12k_base * ab ,
10545
+ struct wmi_mlo_link_set_active_arg * arg )
10546
+ {
10547
+ struct wmi_disallowed_mlo_mode_bitmap_params * disallowed_mode_bmap ;
10548
+ struct wmi_mlo_set_active_link_number_params * link_num_param ;
10549
+ u32 num_link_num_param = 0 , num_vdev_bitmap = 0 ;
10550
+ struct ath12k_wmi_base * wmi_ab = & ab -> wmi_ab ;
10551
+ struct wmi_mlo_link_set_active_cmd * cmd ;
10552
+ u32 num_inactive_vdev_bitmap = 0 ;
10553
+ u32 num_disallow_mode_comb = 0 ;
10554
+ struct wmi_tlv * tlv ;
10555
+ struct sk_buff * skb ;
10556
+ __le32 * vdev_bitmap ;
10557
+ void * buf_ptr ;
10558
+ int i , ret ;
10559
+ u32 len ;
10560
+
10561
+ if (!arg -> num_vdev_bitmap && !arg -> num_link_entry ) {
10562
+ ath12k_warn (ab , "Invalid num_vdev_bitmap and num_link_entry" );
10563
+ return - EINVAL ;
10564
+ }
10565
+
10566
+ switch (arg -> force_mode ) {
10567
+ case WMI_MLO_LINK_FORCE_MODE_ACTIVE_LINK_NUM :
10568
+ case WMI_MLO_LINK_FORCE_MODE_INACTIVE_LINK_NUM :
10569
+ num_link_num_param = arg -> num_link_entry ;
10570
+ fallthrough ;
10571
+ case WMI_MLO_LINK_FORCE_MODE_ACTIVE :
10572
+ case WMI_MLO_LINK_FORCE_MODE_INACTIVE :
10573
+ case WMI_MLO_LINK_FORCE_MODE_NO_FORCE :
10574
+ num_vdev_bitmap = arg -> num_vdev_bitmap ;
10575
+ break ;
10576
+ case WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE :
10577
+ num_vdev_bitmap = arg -> num_vdev_bitmap ;
10578
+ num_inactive_vdev_bitmap = arg -> num_inactive_vdev_bitmap ;
10579
+ break ;
10580
+ default :
10581
+ ath12k_warn (ab , "Invalid force mode: %u" , arg -> force_mode );
10582
+ return - EINVAL ;
10583
+ }
10584
+
10585
+ num_disallow_mode_comb = arg -> num_disallow_mode_comb ;
10586
+ len = sizeof (* cmd ) +
10587
+ TLV_HDR_SIZE + sizeof (* link_num_param ) * num_link_num_param +
10588
+ TLV_HDR_SIZE + sizeof (* vdev_bitmap ) * num_vdev_bitmap +
10589
+ TLV_HDR_SIZE + TLV_HDR_SIZE + TLV_HDR_SIZE +
10590
+ TLV_HDR_SIZE + sizeof (* disallowed_mode_bmap ) * num_disallow_mode_comb ;
10591
+ if (arg -> force_mode == WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE )
10592
+ len += sizeof (* vdev_bitmap ) * num_inactive_vdev_bitmap ;
10593
+
10594
+ skb = ath12k_wmi_alloc_skb (wmi_ab , len );
10595
+ if (!skb )
10596
+ return - ENOMEM ;
10597
+
10598
+ cmd = (struct wmi_mlo_link_set_active_cmd * )skb -> data ;
10599
+ cmd -> tlv_header = ath12k_wmi_tlv_cmd_hdr (WMI_TAG_MLO_LINK_SET_ACTIVE_CMD ,
10600
+ sizeof (* cmd ));
10601
+ cmd -> force_mode = cpu_to_le32 (arg -> force_mode );
10602
+ cmd -> reason = cpu_to_le32 (arg -> reason );
10603
+ ath12k_dbg (ab , ATH12K_DBG_WMI ,
10604
+ "mode %d reason %d num_link_num_param %d num_vdev_bitmap %d inactive %d num_disallow_mode_comb %d" ,
10605
+ arg -> force_mode , arg -> reason , num_link_num_param ,
10606
+ num_vdev_bitmap , num_inactive_vdev_bitmap ,
10607
+ num_disallow_mode_comb );
10608
+
10609
+ buf_ptr = skb -> data + sizeof (* cmd );
10610
+ tlv = buf_ptr ;
10611
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_STRUCT ,
10612
+ sizeof (* link_num_param ) * num_link_num_param );
10613
+ buf_ptr += TLV_HDR_SIZE ;
10614
+
10615
+ if (num_link_num_param ) {
10616
+ cmd -> ctrl_flags =
10617
+ le32_encode_bits (arg -> ctrl_flags .dync_force_link_num ? 1 : 0 ,
10618
+ CRTL_F_DYNC_FORCE_LINK_NUM );
10619
+
10620
+ link_num_param = buf_ptr ;
10621
+ for (i = 0 ; i < num_link_num_param ; i ++ ) {
10622
+ link_num_param -> tlv_header =
10623
+ ath12k_wmi_tlv_cmd_hdr (0 , sizeof (* link_num_param ));
10624
+ link_num_param -> num_of_link =
10625
+ cpu_to_le32 (arg -> link_num [i ].num_of_link );
10626
+ link_num_param -> vdev_type =
10627
+ cpu_to_le32 (arg -> link_num [i ].vdev_type );
10628
+ link_num_param -> vdev_subtype =
10629
+ cpu_to_le32 (arg -> link_num [i ].vdev_subtype );
10630
+ link_num_param -> home_freq =
10631
+ cpu_to_le32 (arg -> link_num [i ].home_freq );
10632
+ ath12k_dbg (ab , ATH12K_DBG_WMI ,
10633
+ "entry %d num_of_link %d vdev type %d subtype %d freq %d control_flags %d" ,
10634
+ i , arg -> link_num [i ].num_of_link ,
10635
+ arg -> link_num [i ].vdev_type ,
10636
+ arg -> link_num [i ].vdev_subtype ,
10637
+ arg -> link_num [i ].home_freq ,
10638
+ __le32_to_cpu (cmd -> ctrl_flags ));
10639
+ link_num_param ++ ;
10640
+ }
10641
+
10642
+ buf_ptr += sizeof (* link_num_param ) * num_link_num_param ;
10643
+ }
10644
+
10645
+ tlv = buf_ptr ;
10646
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_UINT32 ,
10647
+ sizeof (* vdev_bitmap ) * num_vdev_bitmap );
10648
+ buf_ptr += TLV_HDR_SIZE ;
10649
+
10650
+ if (num_vdev_bitmap ) {
10651
+ vdev_bitmap = buf_ptr ;
10652
+ for (i = 0 ; i < num_vdev_bitmap ; i ++ ) {
10653
+ vdev_bitmap [i ] = cpu_to_le32 (arg -> vdev_bitmap [i ]);
10654
+ ath12k_dbg (ab , ATH12K_DBG_WMI , "entry %d vdev_id_bitmap 0x%x" ,
10655
+ i , arg -> vdev_bitmap [i ]);
10656
+ }
10657
+
10658
+ buf_ptr += sizeof (* vdev_bitmap ) * num_vdev_bitmap ;
10659
+ }
10660
+
10661
+ if (arg -> force_mode == WMI_MLO_LINK_FORCE_MODE_ACTIVE_INACTIVE ) {
10662
+ tlv = buf_ptr ;
10663
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_UINT32 ,
10664
+ sizeof (* vdev_bitmap ) *
10665
+ num_inactive_vdev_bitmap );
10666
+ buf_ptr += TLV_HDR_SIZE ;
10667
+
10668
+ if (num_inactive_vdev_bitmap ) {
10669
+ vdev_bitmap = buf_ptr ;
10670
+ for (i = 0 ; i < num_inactive_vdev_bitmap ; i ++ ) {
10671
+ vdev_bitmap [i ] =
10672
+ cpu_to_le32 (arg -> inactive_vdev_bitmap [i ]);
10673
+ ath12k_dbg (ab , ATH12K_DBG_WMI ,
10674
+ "entry %d inactive_vdev_id_bitmap 0x%x" ,
10675
+ i , arg -> inactive_vdev_bitmap [i ]);
10676
+ }
10677
+
10678
+ buf_ptr += sizeof (* vdev_bitmap ) * num_inactive_vdev_bitmap ;
10679
+ }
10680
+ } else {
10681
+ /* add empty vdev bitmap2 tlv */
10682
+ tlv = buf_ptr ;
10683
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_UINT32 , 0 );
10684
+ buf_ptr += TLV_HDR_SIZE ;
10685
+ }
10686
+
10687
+ /* add empty ieee_link_id_bitmap tlv */
10688
+ tlv = buf_ptr ;
10689
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_UINT32 , 0 );
10690
+ buf_ptr += TLV_HDR_SIZE ;
10691
+
10692
+ /* add empty ieee_link_id_bitmap2 tlv */
10693
+ tlv = buf_ptr ;
10694
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_UINT32 , 0 );
10695
+ buf_ptr += TLV_HDR_SIZE ;
10696
+
10697
+ tlv = buf_ptr ;
10698
+ tlv -> header = ath12k_wmi_tlv_hdr (WMI_TAG_ARRAY_STRUCT ,
10699
+ sizeof (* disallowed_mode_bmap ) *
10700
+ arg -> num_disallow_mode_comb );
10701
+ buf_ptr += TLV_HDR_SIZE ;
10702
+
10703
+ ret = ath12k_wmi_fill_disallowed_bmap (ab , buf_ptr , arg );
10704
+ if (ret )
10705
+ goto free_skb ;
10706
+
10707
+ ret = ath12k_wmi_cmd_send (& wmi_ab -> wmi [0 ], skb , WMI_MLO_LINK_SET_ACTIVE_CMDID );
10708
+ if (ret ) {
10709
+ ath12k_warn (ab ,
10710
+ "failed to send WMI_MLO_LINK_SET_ACTIVE_CMDID: %d\n" , ret );
10711
+ goto free_skb ;
10712
+ }
10713
+
10714
+ ath12k_dbg (ab , ATH12K_DBG_WMI , "WMI mlo link set active cmd" );
10715
+
10716
+ return ret ;
10717
+
10718
+ free_skb :
10719
+ dev_kfree_skb (skb );
10720
+ return ret ;
10721
+ }
0 commit comments